我遇到了Spring 3提供的两个注释(@Component和@Configuration)我对它们有点困惑。 这是我读到的关于@Component的内容
把这个“context:component”放在bean配置文件中,就意味着,在Spring中启用自动扫描功能。 base-package指示存储组件的位置,Spring将扫描此文件夹并找出bean(使用@Component注释)并在Spring容器中注册它。
所以我想知道@Configuration的用途是什么,如果@Controller将注册我的bean而不需要在spring配置xml文件中声明它们
@Configuration
是Spring 3中引入的基于Java的配置机制的核心。它提供了基于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
元注释的其他注释之一。
来自Book Pro Spring Integration
@Configuration
类就像常规的@Components
类一样,除了用@Bean
注释的方法用于工厂bean。注意带有@Component
注释方法的@Bean
以相同的方式工作,除了不考虑范围并重新调用@Bean
方法(没有缓存),所以@Configuration
是首选,即使它需要CGLIB
以下是完整示例的区别: -
//@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注释,则a()方法将被调用一次,但b()方法将被调用两次。
(2)中的问题: - 因为我们已经注意到@compenent注释的问题。第二个配置(2)是完全错误的,因为spring将创建一个A的单例bean,但是B将获得一个超出spring上下文控件的A的另一个实例。
解决方案: - 我们可以在Config类中使用带有@component注释的@autowired注释。
@Component
public static class Config {
@Autowired
A a;
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B(a);
}
}
虽然这是旧的,但详细阐述了JavaBoy和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());
}
}