Spring 3中@Component和@Configuration之间的区别

问题描述 投票:12回答:4

我遇到了Spring 3提供的两个注释(@Component@Configuration)我对它们有点困惑。 这是我读到的关于@Component的内容

把这个“context:component”放在bean配置文件中,就意味着,在Spring中启用自动扫描功能。 base-package指示存储组件的位置,Spring将扫描此文件夹并找出bean(使用@Component注释)并在Spring容器中注册它。

所以我想知道@Configuration的用途是什么,如果@Controller将注册我的bean而不需要在spring配置xml文件中声明它们

java spring spring-3
4个回答
9
投票

@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元注释的其他注释之一。


14
投票

来自Book Pro Spring Integration

@Configuration类就像常规的@Components类一样,除了用@Bean注释的方法用于工厂bean。注意带有@Component注释方法的@Bean以相同的方式工作,除了不考虑范围并重新调用@Bean方法(没有缓存),所以@Configuration是首选,即使它需要CGLIB


6
投票

以下是完整示例的区别: -

//@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);
    }
}

2
投票

虽然这是旧的,但详细阐述了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());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.