컴포넌트 스캔과 Spring bean 주입 방식
Spring은 컴포넌트 스캔(component scan)이라는 액션을 통해 생성해야 하는 bean을 찾아 등록한다.
컴포넌트 스캔은 @ComponentScan 애노테이션을 단 클래스가 수행한다. 기본적으로는 해당 클래스가 속한 패키지와, 그 모든 하위 패키지에 존재하는 bean 클래스(즉, @Component가 달린 클래스)를 탐색해 bean 객체로 생성한다.
필요하다면 @ComponentScan 애노테이션의 basePackages 속성에 스캔하고자 하는 패키지를 명시적으로 제한할 수 있다.
@Configuration
@ComponentScan(basePackages = "cholog.scan") // {}를 사용해 복수 표현 가능
public class ContextConfiguration {
}
처음 Spring 애플리케이션을 구현해볼 땐 @ComponentScan을 따로 설정하지도 않았는데 bean이 잘 생성되었었다. 그 이유는 우리가 Spring 애플리케이션 클래스에 적용하는 @SpringBootApplication 애노테이션이 이미 @ComponentScan을 메타 애노테이션으로 사용하고 있기 때문이다. 보통 SpringApplication은 최상위 레벨의 패키지에 두기 때문에 @Component 클래스들이 감지되었던 것이다.
Bean에 대한 의존성 주입
Bean을 다른 bean에 주입하는 방법은 여러가지 있다.
1. 필드에 @Autowired 애노테이션 사용
가장 간단한 방식이다. 클래스 필드에 @Autowired 애노테이션을 붙여주기만 하면 된다.
@Service
public class FieldInjection {
@Autowired
private InjectionBean injectionBean;
}
2. 생성자를 통해 주입
생성자에 다른 bean을 매개변수로 받도록 구현하면 Spring이 대신 인자를 전달해준다.
@Service
public class ConstructorInjection {
private InjectionBean injectionBean;
public ConstructorInjection(InjectionBean injectionBean) {
this.injectionBean = injectionBean;
}
}
3. Setter 메서드
Setter 메서드를 구현해 bean을 주입할 수도 있다. 이때 setter 메서드에는 필드 주입과 마찬가지로 @Autowired 애노테이션을 필요로 한다.
@Service
public class SetterInjection {
private InjectionBean injectionBean;
@Autowired
public void setInjectionBean(InjectionBean injectionBean) {
this.injectionBean = injectionBean;
}
}