Spring framwork단위에서 인스턴스를 관리하기 위해서 Configuration과 Component는 항상 사용한다.
외부 라이브러리 설정들을 메소드 단위로 @Bean
을 등록할 때는 클래스에 @Configuration
을 넣어주고 Service, Controller, Repository 뿐만 아니라 클래스 단위의 정의는 @Component
를 넣어준다.
그런데 문득 생각이 들었다.
두 어노테이션은 내부적으로 어떤 차이가 있을까?
@Target(ElementType.TYPE)
: 클래스, 인터페이스(포함 어노테이션), 또는 열거형에 어노테이션을 선언할 수 있음.@Retention(RetentionPolicy.RUNTIME)
: @Component
어노테이션은 런타임에도 JVM에 의해 참조될 수 있음을 의미합니다. 클래스, 메소드, 필드에 대한 어노테이션 정보를 런타임에 읽을 수 있음을 의미@Documented
: 문서화 될 때 해당 어노테이션이 JavaDoc에 포함되도록 지시@Indexed
: 스프링 프레임워크가 해당 컴포넌트를 빠르게 찾을 수 있도록 인덱싱(@ComponentScan
와 유사)@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
String value() default "";
: @Component
어노테이션을 사용할 때 선택적으로 값을 제공할 수 있음. 이 값은 대체로 빈 이름으로 사용됩니다.@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class) // 다른점1
String value() default "";
boolean proxyBeanMethods() default true; // 다른점2
}
@AliasFor(annotation = Component.class)
: @Component
의 value속성과 동일하게 동작하도록 선언하는 것boolean proxyBeanMethods() defalt true
: true일 때, 메소드 호출을 통해 Bean이 이미 등록되어있는지 확인하고 필요한 경우 새로운 Bean을 생성하는 프록시가 생성됨. (싱글턴 Bean 보장 제어)@Configuration
이 붙은 클래스는 스프링의 CGLIB 프록시를 사용해서 정의했던 @Bean
를 호출하면 싱글턴을 보장해준다고 한다.@Component
에 지정을 한다면 @Bean
을 사용한 메소드의 반환 값이 싱글턴을 보장해주지 못할 수 있다고 한다.
가치 있는 정보 공유해주셔서 감사합니다.