@Bean과 @Component 차이점
개발을 하다보니 @Component 어노테이션을 많이 사용하게 되었다. 특히 팩토리 패턴에서는 팩토리 역할을 하는 객체 및 팩토리 객체에서 생성되는 객체들을 @Component 어노테이션을 붙여 빈 생성을 하게 되었다.
그러다보니 언뜻 들은 @Bean 어노테이션도 들었는데 빈을 생성하는데 @Bean과 @Component 어노테이션 둘의 차이 점은 무엇일까?
둘다 빈으로 등록되게 하고 관리되게 해주는 것이지만 살짝 차이 점이 있다.
@Bean
외부 라이브러리 또는 이미 정의되어 있는 객체들이 서로 종속성을 가지고 있을 경우의 빈 등록에 사용하는 어노테이션이다. 반환 값이 바로 Bean으로 등록되는 것이다. 이미 정의된 기본 객체를 재정의하거나 내가 만든 객체의 종속성을 위해 빈을 등록할 때 사용한다.
즉, 메소드 단위에서 개발자가 외부 라이브러리 및 개발자가 정의하지 않은 객체를 유연하게 넘기기 위해 사용하는 어노테이션이다.
public Class TestObject {
@Bean
public List test() {
return new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
}
}
public Class Test {
@Bean
publid Test1 test1() { return new Test1(test2());
@Bean
public Test2 test2() { return new Test2(); }
}
또한 @Bean 어노테이션의 타켓은 아래와 같아서 @Bean 어노테이션은 메소드에 붙일 수 있다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Component
개발자가 직접 정의한 객체 클래스 자체를 빈 등록할 때 사용하는 어노테이션이다. 개발하면서 @Bean보다 @Componet 어노테이션을 더 많이 사용했었다.
@Component
public Class TestObject {
public void test() {...}
}
@Componet 어노테이션은 타켓은 Type으로 클래스, 인터페이스, 열거형에 붙일 수 있다. 즉, 객체 단위에 해당 어노테이션을 붙인다고 보면 된다.
@Target(ElementType.TYPE)
@Bean과 @Component를 바꿔서 사용할 수 있을까?
이 질문도 종종 보이는데 답은 '아니다.'
둘의 Target이 아예 달라서 둘을 바궈서 사용할 수는 없다.
- @Bean
@Bean은 Target이 METHO, ANNOTATION_TYPE으로 정해져 있어서 함수 단위 또는 어노테이션 단위에 사용해야한다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
- @Componet
@Componet는 Target이 TYPE이므로 클래스, 인터페이스, 열거형에 붙일 수 있다.
@Target(ElementType.TYPE)
즉, 둘의 Target은 달라서 각각의 Target에 맞게 같이는 사용해도 둘을 서로 바꿔서 사용할 수는 없다.
만일 각 Target에 맞추지 않고 바꿔 사용했을 경우 컴파일 에러가 발생한다.
✋ ElementType 종류
https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html