@Configuration 애노테이션의 주요 목적
내가 만든 Spring bean 클래스(@Component 애노테이션이 달린 클래스)가 실제로 IoC 컨테이너에 bean으로 등록되려면 컴포넌트 스캔 과정을 거치거나 @Configuration 클래스가 생성하도록 구현해야 한다.
@Configuration으로 bean을 생성한다면 보통 아래처럼 코드를 작성하는데,
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
이때 @Bean 애노테이션만 있다면 @Configuration이 없어도 bean이 생성된다. Bean을 등록하는 데에 있어 반드시 @Configuration이 필요한 건 아니다. (대신 최소한 @Component는 필요하다. AppConfig 클래스가 bean으로 인식되어야 해당 클래스에 구현된 @Bean 생성 메서드가 정상적으로 호출되기 때문)
그렇다면 @Configuration의 역할은 무엇인가?
@Configuration 애노테이션은 @Bean이 싱글톤으로 생성되도록 보장해준다.
// AppConfig.java
@Component
public class AppConfig {
@Bean
public MyService myService() {
System.out.println("--- myService() 호출 ---");
return new MyService(myRepository()); // MyService는 MyRepository를 주입 받는다
}
@Bean
public MyRepository myRepository() {
System.out.println("--- myRepository() 호출 ---");
return new MyRepository();
}
}
// MyService.java
public class MyService {
private final MyRepository myRepository;
public MyService(MyRepository myRepository) {
this.myRepository = myRepository;
System.out.println("MyService 생성");
}
}
// MyRepository.java
public class MyRepository {
public MyRepository() {
System.out.println("MyRepository 생성");
}
}
위 코드로 애플리케이션을 실행해보면 "MyRepository 생성"이 두 번 출력된다. MyRepository와 MyService bean을 각각 등록할 때 호출되는 myRepository() 메서드가 매번 새로운 MyRepository 인스턴스를 만들어 반환하는 것이다.
하지만 @Component를 @Configuration으로 바꾸면, 해당 문구가 한 번만 출력된다.
만약 bean 간의 의존성이 복잡하게 얽혀있는 구조라면 @Configuration 애노테이션으로 bean을 싱글톤으로 관리하도록 해야 인스턴스가 줄줄이 생성되지 않을 것이다.
참고로 @Scope 애노테이션으로 싱글톤이 아닌 bean을 생성하도록 설정할 수 있다. 다만 @Configuration과 @ComponentScan에게 맡기면 디폴트로 싱글톤 bean을 만들어준다.
참고: