Разница между @Component и @Configuration в Spring 3

Я встретил две аннотации, предоставленные Spring 3 (@Компонент и @Конфигурация) Я немного смущен между ними.
Вот что я читал о @Component

Поместите этот "context: component" в конфигурационный файл bean, это означает, включить функцию автоматического сканирования в Spring. Базовый пакет указывает где хранятся ваши компоненты, Spring сканирует эту папку и узнайте bean (аннотированный с @Component) и зарегистрируйте его в Spring.

Итак, мне интересно, что такое @Configuration, если @Controller зарегистрирует мой beans без необходимости объявлять их в Spring файле конфигурации xml

Ответ 1

@Configuration является основой механизма конфигурации на Java, который был представлен в Spring 3. Он предоставляет альтернативу конфигурации на основе XML.

Итак, следующие два фрагмента идентичны:

<beans ...>
    <context:component-scan base-package="my.base.package"/>
    ... other configuration ...
</beans>

и

@Configuration
@ComponentScan(basePackages = "my.base.package")
public class RootConfig {
    ... other configuration ...
}

В обоих случаях Spring будет сканировать в my.base.package и ниже для классов, аннотированных с помощью @Component, или одной из других аннотаций, которые мета-аннотируются с помощью @Component, таких как @Service.

Ответ 2

Из книги Pro Spring Интеграция

@Configuration классы аналогичны обычным классам @Components, за исключением того, что методы, аннотированные с помощью @Bean, используются для factory beans. Обратите внимание, что аннотированные методы @Component с @Bean работают одинаково, за исключением того, что области видимости не соблюдаются и методы @Bean повторно вызываются (без кэширования в игре), поэтому @Configuration является предпочтительным, хотя это требуется CGLIB

Ответ 3

Вот разница с полным примером: -

//@Configuration or @Component
public static class Config {
    @Bean
    public A a() {
        return new A();
    }
    //**please see a() method called inside b() method**
    @Bean
    public B b() {
        return new B(a());
    }
}

1) Здесь, если класс Config, аннотированный @configuration, чем метод a() и метод b(), оба будут вызваны один раз.

2) Здесь, если класс Config аннотирован @component, метод b() будет вызван один раз, а метод() будет вызван дважды.

Проблема в (2): - поскольку мы заметили проблему с аннотацией @component. Эта вторая конфигурация (2) совершенно неверна, потому что spring создаст одноэлементный компонент A, но B получит другой экземпляр A, который находится вне контекста управления Spring.

Решение: - мы можем использовать аннотацию @autowired с аннотацией @component внутри класса Config.

@Component
public static class Config {
    @Autowired
    A a;

    @Bean
    public A a() {
        return new A();
    }

    @Bean
    public B b() {
        return new B(a);
    }
}

Ответ 4

Хотя это и старо, но, основываясь на ответах JavaBoy And Vijay, на примере:

@Configuration
public class JavaConfig {
    @Bean
    public A getA() {
        return new A();
    }
}

@Component
@ComponentScan(basePackages="spring.example")
public class Main() {
    @Bean
    public B getB() {
        return new B();
    }
    @Autowired
    JavaConfig config;

    public static void main(String[]a) {
        Main m = new AnnotationConfigApplicationContext(Main.class)
            .getBean(Main.class);
        /* Different bean returned everytime on calling Main.getB() */
        System.out.println(m.getB());
        System.out.println(m.getB());
        /* Same bean returned everytime on calling JavaConfig.getA() */
        System.out.println(m.config.getA());
        System.out.println(m.config.getA());
    }
}

Ответ 5

@Component - это общая аннотация стереотипа, которая может указывать на любой из компонентов-кандидатов, т.е. @Repository, @Service, @Controller и эти кандидаты имеют право на автоопределение.

В то время как @Configuration используется для создания компонента, который используется @Configuration Framework для создания контекста приложения, внутренне @Configuration использует @Component поэтому имеет смысл даже быть тем пружинным компонентом, который создает сама среда.