[java] 스프링 : @Component 대 @Bean

@Component클래스 패스 스캐닝을 사용하여 xml bean 정의를 제거하기 위해 주석이 스프링 2.5에 도입 되었다는 것을 이해합니다 .

@Bean는 스프링 3.0에서 도입되었으며 @Configurationxml 파일을 완전히 제거하고 대신 java config를 사용하기 위해 사용할 수 있습니다 .

@Component주석을 도입하는 대신 주석 을 재사용 할 수 @Bean있었습니까? 내 이해는 최종 목표가 두 경우 모두에서 콩을 만드는 것입니다.



답변

@Component그리고 @Bean두 개의 아주 다른 일을하고 혼동해서는 안됩니다.

@Component(및 @Service@Repository)는 클래스 경로 검색을 사용하여 Bean을 자동 감지하고 자동 구성하는 데 사용됩니다. 어노테이션이있는 클래스와 Bean (즉, 클래스 당 하나의 Bean) 사이에 암시 적 일대일 맵핑이 있습니다. 이 제어 방식은 순전히 선언적이므로 배선 제어가 상당히 제한됩니다.

@Bean위와 같이 Spring이 자동으로 수행하도록하는 대신 단일 Bean 을 명시 적으로 선언하는 데 사용됩니다 . 클래스 정의에서 Bean 선언을 분리하고 원하는 방식으로 Bean을 작성하고 구성 할 수 있습니다.

질문에 대답하려면 …

@Component주석을 도입하는 대신 주석 을 재사용 할 수 있었 @Bean습니까?

아마; 그러나 그들은 서로 다르기 때문에 선택하지 않았습니다. 봄은 이미 물을 더럽 히지 않고 충분히 혼란 스럽습니다.


답변

@Component
구성 요소 스캔 및 자동 배선에 적합합니다.

언제 @Bean 을 사용해야 합니까?

때로는 자동 구성이 옵션이 아닙니다. 언제? 타사 라이브러리의 구성 요소를 연결하려고한다고 가정합니다 (소스 코드가 없으므로 클래스에 @Component로 주석을 달 수 없으므로) 자동 구성이 불가능합니다.

@Bean 어노테이션은 객체 반환 스프링 애플리케이션 컨텍스트 내에서 빈으로 등록해야합니다. 방법의 몸은 인스턴스를 생성을 담당하는 로직을 맺는다.


답변

동적 상태에 따라 특정 구현을 원한다고 가정 해 봅시다.
@Bean이 경우에 완벽합니다.

@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
    case 1:
        return new Impl1();
    case 2:
        return new Impl2();
    case 3:
        return new Impl3();
    default:
        return new Impl();
    }
}

그러나와 함께 할 수있는 방법은 없습니다 @Component.


답변

  1. @Component auto는 classpath 스캐닝을 사용하여 bean을 감지 하고 구성하는 반면 @Bean Spring이 자동으로 수행하지 않고 단일 bean을 명시 적으로 선언 합니다.
  2. @Component 클래스 정의에서 Bean 선언을 분리 합니다. @Bean은 Bean 정의를 클래스 정의에서 분리 합니다.
  3. @Component는 클래스 레벨 주석 인 반면 @Bean은 메소드 레벨 주석 이며 메소드 이름은 Bean 이름으로 사용됩니다.
  4. @Component 어노테이션 은 @Configuration 주석 이 달린 클래스 내에서 사용해야 하는 @Configuration 어노테이션 과 함께 사용될 필요는 없습니다 .
  5. 우리는 빈 만들 수 없습니다 클래스는 우리가 반면 외부 스프링 컨테이너의 경우, @Component를 사용하여 클래스를 빈 만들 수 클래스가 존재하는 경우 @Bean도를 사용하여 클래스를 외부 스프링 컨테이너가 .
  6. @Component에는 @Controller, @Repository 및 @Service와 같은 다른 특수화 가 있지만 @Bean에는 특수화없습니다 .

답변

두 접근법 모두 Spring 컨테이너에 대상 유형을 등록하는 것을 목표로합니다.

차이점은 메소드 에는 적용 가능 하지만 유형 에는 적용 @Bean가능 하다는 것 입니다 .@Component

따라서 @Bean주석 을 사용할 때 메소드 본문에서 인스턴스 작성 로직을 제어합니다 ( 위 예제 참조 ). 로 다음 @Component주석 당신은 할 수 없습니다.


답변

나는 많은 대답을 보았고 거의 모든 곳에서 언급 된 @Component는 컴포넌트가 스캔되는 곳의 autowiring을위한 것이고 @Bean은 그 bean이 다르게 사용될 것이라고 정확하게 선언하고있다. 어떻게 다른지 보여 드리겠습니다.

  • @콩

먼저 메소드 레벨 주석입니다. 두 번째로 일반적으로 Java 코드에서 Bean을 구성하고 (xml 구성을 사용하지 않는 경우) ApplicationContext의 getBean 메소드를 사용하여 클래스에서 Bean을 호출하는 데 사용합니다. 처럼

 @Configuration
class MyConfiguration{
    @Bean
    public User getUser(){
        return new User();
    }
}

class User{
}



//Getting Bean 
User user = applicationContext.getBean("getUser");
  • @구성 요소

특수 bean이 아닌 bean에 주석을 달기위한 일반적인 방법입니다. 클래스 레벨 주석이며 Java 또는 xml 구성을 통해 모든 구성 요소를 피하는 데 사용됩니다.

우리는 이와 같은 것을 얻습니다.

@Component
class User {
}

//to get Bean
@Autowired
User user;

그게 다야. 해당 Bean을 인스턴스화하고 사용하기위한 모든 구성 단계를 피하기 위해 방금 소개되었습니다.


답변

@BeanSpring 프레임 워크 애플리케이션 컨텍스트에서 기존 써드 파티 클래스를 사용 가능하게하는 데 사용할 수 있습니다 .

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}

@Bean주석 을 사용하면 써드 파티 클래스 ( @Component스프링이 없을 수도 있고 사용하지 않을 수도 있음)를 스프링 Bean으로 랩핑 할 수 있습니다 . 그런 다음을 사용하여 @Bean감싸면 단일 객체로 사용되며 Spring 프레임 워크 응용 프로그램 컨텍스트에서 사용할 수 있습니다. 종속성 주입 및을 사용하여 앱에서이 Bean을 쉽게 공유 / 재사용 할 수 있습니다 @Autowired.

@Bean주석은 타사 클래스의 래퍼 / 어댑터 라고 생각하십시오 . Spring 프레임 워크 애플리케이션 컨텍스트에서 써드 파티 클래스를 사용 가능하게하려고합니다.

@Bean위의 코드에서 사용 하면 메소드 내부에서 new키워드를 사용하여 명시 적으로 객체를 작성하기 때문에 단일 Bean을 명시 적으로 선언 합니다. 또한 주어진 클래스의 setter 메소드를 수동으로 호출합니다. 그래서 접두사 필드의 값을 변경할 수 있습니다. 따라서이 수동 작업을 명시 적 작성이라고합니다. @Component동일한 클래스에 대해를 사용하면 Spring 컨테이너에 등록 된 Bean은 접두사 필드의 기본값을 갖습니다.

반면에로 클래스에 주석을 달 때 키워드 @Component를 수동으로 사용할 필요가 없습니다 new. Spring이 자동으로 처리합니다.