Spring 입문4

  1. 컴포넌트 스캔
    1-1 컴포넌트 스캔과 의존관계 자동 주입 시작하기
    – 기존의 @Bean 방식을 @Component 방식으로 변경
    – AppConfig에 @Configuration과 @ComponentScan 애노테이션을 설정
    – 이 때 @ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록
    – 각 클래스가 컴포넌트 스캔의 대상이 되도록 @Component 애노테이션을 각각 붙임
    – ServiceImpl등 생성자로 Repository 따위를 전달 받는 곳에 @Autowired를 통해 의존관계를 자동으로 주입 받음 (스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입)

    1-2 기본 스캔 대상
    – 컴포넌트 스캔은 @Component 뿐만 아니라 아래 내용도 추가로 대상에 포함
    — @Component : 컴포넌트 스캔에서 사용
    — @Controlller : 스프링 MVC 컨트롤러에서 사용 (스프링 MVC 컨트롤러로 인식)
    — @Service : 스프링 비즈니스 로직에서 사용 (스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환)
    — @Repository : 스프링 데이터 접근 계층에서 사용 (스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리)
    — @Configuration : 스프링 설정 정보에서 사용

    1-3 필터
    – includeFilters : 컴포넌트 스캔 대상을 추가로 지정
    – excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정
    – FilterType 옵션
    — ANNOTATION: 기본값, 애노테이션을 인식해서 동작한다.
    ex) org.example.SomeAnnotation
    — ASSIGNABLE_TYPE: 지정한 타입과 자식 타입을 인식해서 동작한다.
    ex) org.example.SomeClass
    — ASPECTJ: AspectJ 패턴 사용
    ex) org.example..Service+ REGEX: 정규 표현식 ex) org.example.Default.
    — CUSTOM: TypeFilter 이라는 인터페이스를 구현해서 처리
    ex) org.example.MyTypeFilter

    1-4 중복 등록과 충돌
    – 자동빈 등록 vs 자동 빈 등록
    — 컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록
    — 이름이 같은 경우 스프링은 오류를 발생 (ConflictingBeanDefinitionException)

    – 수동 빈 등록 vs 자동 빈 등록
    — 수동 빈 등록이 우선권을 가짐 ( 수동 빈이 자동 빈을 오버라이딩)


  2. 의존관계 자동 주입
    2-1 다양한 의존 과계 주입 방법
    – 생성자 주입 (권장)
    — 생성자 호출시점에서 딱 1 번만 호출되는 것이 보장
    — 불변, 필수 의존관계에 사용

    – 수정자 주입 (setter 주입)
    — setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해 의존관계를 주입
    — 선택, 변경 가능성이 있는 의존관계에 사용
    — 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용

    – 필드 주입
    — 코드가 간결
    — 외부에서 변경이 불가능해서 테스트 하기 힘들다는 단점
    — DI 프레임워크 없이 불가
    — 사용 자제

    – 일반 메서드 주입
    — 한번에 여러 필드를 주입 가능
    — 일반적으로 사용하지 않음

    2-2 옵션 처리
    – 주입할 스프링 빈이 없어도 동작을 필요로 할 때가 있음
    – @Autowired만 사용하면 required 옵션의 기본값이 true로 되어 있어 자동 주입 대상이 없으면 오류를 발생
    – 자동 주입 대상을 옵션으로 처리하는 방법
    — @Autowired(required=false) : 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출 안 됨
    — org.springframework.lang.@Nullable : 자동 주입할 대상이 없으면 null이 입력
    — Optional<> : 자동 주입할 대상이 없으면 Optional.empty 가 입력

    2-3 생성자 주입 선택 권장 (결론)
    – 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없음
    – 오히려 대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안 됨 (불변)
    – 수정자 주입을 사용하면, setXxx 메서드를 public으로 열어두어야 함
    – 누군가 실수로 변경할 수 도 있고, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아님
    – 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없음, 따라서 불변하게 설계할 수 있음
    – final 키워드
    — 생성자 주입을 사용하면 필드에 final 키워드 사용 가능
    — 생성자에 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에서 막아줌

    2-4 롬복 라이브러리
    – @RequiredArgsConstructor : final이 붙은 필드를 모아서 생성자를 자동으로 만들어 줌 (롬복이 자바의 애노테이션 프로세서라는 기능을 이용)


  3. 빈 생명주기 콜백
    3-1 빈 생명주기 콜백 시작
    데이터베이스 커넥션 풀이나, 네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요

    – 스프링 빈의 라이프사이클 (간략화) : 객체 생성 -> 의존관계 주입
    — 스프링 빈은 객체를 생성하고, 의존관계 주입이 다 끝난 다음에야 필요한 데이터를 사용할 수 있는 준비가 완료
    — 따라서 초기화 작업은 의존관계 주입이 모두 완료되고 난 다음에 호출해야 함
    — 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공
    — 스프링은 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 줌
    — 따라서 안전하게 종료 작업 진행 가능

    스프링 빈의 이벤트 라이프사이클
    ( 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료 )
    – 초기화 콜백 : 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
    – 소멸전 콜백 : 빈이 소멸되기 직전에 호출
    ( 참고 : 생성자는 필수 정보(파라미터)를 받고, 메모리를 할당해서 객체를 생성하는 책임을 가진다. 반면에 초기화는 이렇게 생성된 값들을 활용해서 외부 커넥션을 연결하는등 무거운 동작을 수행한다. 따라서 생성자 안에서 무거운 초기화 작업을 함께 하는 것 보다는 객체를 생성하는 부분과 초기화 하는 부분을 명확하게 나누는 것이 유지보수 관점에서 좋다. 물론 초기화 작업이 내부 값들만 약간 변경하는 정도로 단순한 경우에는 생성자에서 한번에 다 처리하는게 더 나을 수 있다. )

    – 스프링 빈 생명주기 콜백 방법 
    — 1. 인터페이스 InitializingBean, DisposableBean
    — InitializingBean, DisposableBean를 implements하여 클래스 생성
    — InitializingBean 은 afterPropertiesSet() 메서드로 초기화를 지원
    — DisposableBean 은 destroy() 메서드로 소멸을 지원
    — 초기화, 소멸 인터페이스 단점 : 각 인터페이스는 스프링 전용 인터페이스이므로 해당 코드가 의존 ( 메서드 이름 변경 불가, 내가 코드를 고칠 수 없는 외부 라이브러리에 적용 불가 – 거의 사용하지 않음 )
    — 2. 빈 등록 초기화, 소멸 메서드 지정
    — 설정 정보에 @Bean(initMethod = “init”, destroyMethod = “close”) 처럼 초기화, 소멸 메서드를
    지정 가능
    — 자유로운 메서드 이름 수정
    — 스프링 빈이 스프링 코드에 의존하지 않음
    — 코드가 아니라 설정 정보를 사용하기 떄문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있음
    — 3. 애노테이션 @PostConstruct, @PreDestroy (권장)
    — 최신 스프링에 가장 권장되는 방법
    — 애노테이션 하나만 붙이면 되므로 매우 편리
    — 스프링 종속적 기술이 아닌 JSR-250라는 자바 표준 ( 패키지 javax.annotation.PostConstruct )
    — 단점 : 외부 라이브러리에 적용 불가, 외부 라이브러리를 초기화, 종료 해야 하면 @Bean의 기능을 사용

◆ 그 외 사항

포스팅 계획 –  4월 : MVC 모델링, 정처기 실기(+중간) / 5월 : 스프링부트, MVC 모델링 / 6월 : 졸업 작품(+기말) / 7월 : 스프링부트 / 8월 ~ : 알고리즘과 CS, JPA, 스프링부트를 포함한 미정

  • 아직 해당 작성글에 틀린 부분이 많은 것으로 예상됩니다. 언제나 댓글 환영입니다
  • 그리고 이 글은 인프런 김영한 선생님의 Spring 로드맵 과정입니다

 

댓글 남기기