▶CodeStates Back-End/Section 2

TIL [0617] Spring DI & @componentScan

휴학생감자 2022. 6. 22. 13:43

 

Sptring DI, 스프링에서의 의존관계 주입 방법

 

① 생성자 주입

생성자를 통해서 의존 관계를 주입받는 방법

생성자에 @Autowired를 붙여주면 스프링 컨테이너에 @Component로 등록된 빈에서 생성자에 필요한 빈을 주입함.

 

# 특징

생성자 호출 시점에 딱 1번만 호출되며, 생성자가 1개만 존재하는 경우에는 @Autowired를 생략해도 자동으로 주입된다.

주입받을 필드를 final로 선언할 수 있고, NullPointerException을 방지할 수 있다.

(스프링이 클래스의 객체를 생성해서 빈에 넣는데 생성자가 반드시 호출되므로 1개인 경우에만 생략가능하다.)

 

 

② 수정자 주입(setter이용)

setter 메서드를 통해서 의존 관계를 주입하는 방법

 

# 특징

변경 가능성이 있는 의존 관계에 사용할 수 있다.

@Component가 실행하는 클래스가 스프링 빈으로 등록된 후에 의존 관계 주입이 이루어지므로, @Autowired를 입력하지 않으면 실행이 안된다. 

 

 

③ 필드 주입

필드에 @Autowired를 붙여서 바로 의존관계를 주입하는 방법

 

# 특징

코드가 간결해서 많이 사용되던 방법이지만, 외부에서 변경이 불가능하여 테스트가 힘들다.

DI 프레임워크가 없으면 아무것도 못하며, 실제 코드와 상관없는 특정 테스트를 하고 싶을 때 사용가능하다.

 

 

④ 일반 메서드 주입

일반 메서드를 사용하여 의존관계를 주입하는 방법

 

# 특징

한번에 여러 개의 필드를 주입받을 수 있으나, 일반적으로 사용되는 방법은 아니다.

 

 


 

 

★생성자 주입을 사용하는 이유

- 생성자 주입은 객체를 생성할 때 최초로 1번만 호출되고 그 이후에는 다시 호출되지 않으므로 불변하게 설계할 수 있다.

- 의존관계 주입이 필요한 데이터 누락 시 컴파일 오류가 발생한다.

- 필드에 final 키워드를 사용할 수 있다.

- 순환 참조를 방지하여, 애플리케이션 구동 이전에 문제를 확인할 수 있다.(BeanCurrentlyInCreationException)

- 테스트 코드 작성이 용이하다.

 

 

 


 

 

 

@ComponentScan

 

설정 정보없이 자동으로 스프링 빈을 등록하는 기능

 

스프링 빈을 등록할 때는 @Bean 또는 XML 등의 설정 정보를 직접 등록하였으나, 이 경우에는 다양한 문제가 발생할 수 있다.

@Component가 붙은 모든 클래스를 스프링 빈으로 등록해주므로 설정 정보에 @ComponentScan만 붙여주는 방법이 제공된다.

의존관계를 자동으로 주입하는 @Autowired 기능도 제공한다.

 

basePackages 매개변수를 통해 탐색할 패키지의 시작 위치를 지정할 수 있고, 해당 패키지의 하위 패키지 전체를 탐색한다.

지정하지 않는 경우에는 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.

설정 정보 클래스의 위치를 프로젝트의 최상단에 두면 편리하다.

(스프링 부트 사용 시, @SpringBootApplication을 시작 루트에 두는 것을 추천함 → @ComponentScan이 포함되어 있으므로)

 

 

※ 주의사항

@ComponentScan은 @Configuration이 붙은 설정 정보도 자동으로 등록하므로 기존에 작성한 AppConfig가 있다면 정상적인 작동이 되지 않는다.

이런 경우, @Configuration이 붙어있는 파일에

" @ComponentScan(excludeFilters = @Filter(type=FilterType.ANNOTATION, classes = Configuration.class)) "

를 붙여주면 해결된다.

 

 

# 컴포넌트 스캔의 기본 대상

   @Component : 컴포넌트 스캔에서 사용

   @Controller & @RestController : 스프링 MVC 및 REST 전용 컨트롤러에서 사용

   @Service : 스프링 비즈니스 로직에서 사용 (특별한 처리 없이 계층을 인식하는데 인식에 도움이 됨.)

   @Repository : 스프링 데이터 접근 계층에서 사용 (데이터 계층의 예외를 스프링 예외로 변환함.)

   @Configuration : 스프링 설정 정보에 사용 (스프링 빈이 싱글톤을 유지하도록 추가적인 처리를 함.)