首页 文章

Spring:@Component与@Bean

提问于
浏览
266

我知道在第2.5版中引入了 @Component 注释,以便通过使用类路径扫描来消除xml bean定义 .

@Bean 是在Spring 3.0中引入的,可以与 @Configuration 一起使用,以便完全摆脱xml文件并使用java配置 .

是否可以重复使用 @Component 注释而不是引入 @Bean 注释?我的理解是,最终目标是在两种情况下都创建bean .

8 回答

  • 53

    @Component@Bean 做两件完全不同的事情,不应该混淆 .

    @Component (和 @Service@Repository )用于使用类路径扫描自动检测和自动配置bean . 有's an implicit one-to-one mapping between the annotated class and the bean (i.e. one bean per class). Control of wiring is quite limited with this approach, since it' s纯粹是声明性的 .

    @Bean 用于显式声明单个bean,而不是让Spring像上面那样自动执行它 . 它将bean的声明与类定义分离,并允许您根据自己的选择创建和配置bean .

    回答你的问题......

    是否可以重用@Component注释而不是引入@Bean注释?

    当然可能;但他们选择不这样做,因为两者完全不同 . Spring 天已经足够混乱,没有进一步混淆水域 .

  • 184

    @Component 优先用于元件扫描和自动布线 .

    你什么时候应该使用 @Bean

    有时自动配置不是一种选择 . When? 让's imagine that you want to wire components from 3rd-party libraries (you don' t拥有源代码,因此您无法使用@Component注释其类,因此无法进行自动配置 .

    @Bean 注释 returns an object 那个spring应该在应用程序上下文中注册为bean . body of the method 承担负责创建实例的逻辑 .

  • 9

    让我们考虑一下我需要具体的实现,具体取决于一些动态状态 . @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 无法做到这一点 .

  • 24

    这两种方法都旨在在Spring容器中注册目标类型 .

    区别在于 @Bean 适用于 methods ,而 @Component 适用于 types .

    因此,当您使用 @Bean 注释时,您可以控制方法体中的实例创建逻辑(请参阅example above) . 使用 @Component 注释,您不能 .

  • 297
    • @Component auto detects 并使用类路径扫描配置bean,而@Bean explicitly declares 使用单个bean,而不是让Spring自动执行 .

    • @Component does not decouple 来自类定义的bean的声明,其中@Bean decouples 从类定义中声明bean .

    • @Component是 class level annotation ,其中@Bean是 method level annotation ,方法的名称用作bean名称 .

    • @Component need not to be used with the @Configuration 注释,其中@Bean注释必须为 used within the class which is annotated with @Configuration .

    • 我们_2328454_使用@Component的类,如果该类在spring容器之外,而我们 can create a bean 是使用@Bean的类,即使该类存在 outside the spring container .

    • @Component有 different specializations ,如@ Controller,@ Repository和@Service,而@Bean有 no specializations .

  • 3

    @Component 这是一个通用注释,可以应用于应用程序的任何类,使其成为 spring 管理组件(简单地说,是任何 spring 管理组件的通用构造型) . 当类路径被spring的component-scan (@ComponentScan) 特征扫描时,它将识别用 @Component 注释(在给定包中)注释的类,并创建这些类的bean并在ApplicationContext中注册它们 . @Component 是类级别注释,其目的是使类成为类路径扫描功能的 spring 托管组件和自动检测bean .

    如果您想了解更多关于 @Component 和其他刻板印象的注释,建议您查看这篇文章 .

    @Bean 用于在从方法返回的Spring IOC容器中显式声明和注册bean(作为配置bean) . @Bean是一个方法级注释,它在一个用 @Configuration 注释的类中使用 . 简单地说, @Bean 注释用于将方法返回的bean注册为IOC Container中的spring配置bean . @Bean 只是一个方法级注释,不能与类和对象声明一起使用 .

    @Bean 注释表明一个方法生成一个应该由bean管理的bean spring 容器 .

    要声明bean,只需使用 @Bean 注释注释方法即可 . 当JavaConfig遇到这样的方法时,它将执行该方法并将返回值注册为ApplicationContext中的bean . 默认情况下,bean名称将与方法名称相同 . 以下是@Bean方法声明的简单示例 .

    @Configuration
    public class ApplicationConfig {
    
        @Bean
        public User adminUserProfile() {
            return new User("Rami","Nassar");
        }
    }
    

    在ApplicationConfig类中,您可以看到我们首先使用 @Configuration 批注来通知Spring这是一个基于Java的配置文件 . 之后, @Bean 注释用于声明Spring bean和DI要求 . @Bean 注释等效于 **** 标记,方法名称等同于 **** 标记内的id属性 . 我希望在阅读本文之后,您已经清楚了解 @Bean@Component 注释的真实目的和用法 .

  • 129

    当您使用 @Component 标记时,它与具有vanilla bean声明方法(使用 @Bean 注释)的POJO(Plain Old Java Object)相同 . 例如,以下方法1和2将给出相同的结果 .

    Method 1

    @Component
    public class SomeClass {
    
        private int number;
    
        public SomeClass(Integer theNumber){
            this.number = theNumber.intValue();
        }
    
        public int getNumber(){
            return this.number;
        }
    }
    

    用'theNumber'的 beans 子:

    @Bean
    Integer theNumber(){
        return new Integer(3456);
    }
    

    Method 2

    //Note: no @Component tag
    public class SomeClass {
    
        private int number;
    
        public SomeClass(Integer theNumber){
            this.number = theNumber.intValue();
        }
    
        public int getNumber(){
            return this.number;
        }
    }
    

    与两者的 beans :

    @Bean
    Integer theNumber(){
        return new Integer(3456);
    }
    
    @Bean
    SomeClass someClass(Integer theNumber){
        return new SomeClass(theNumber);
    }
    

    方法2允许您将bean声明保持在一起,它更灵活等等 . 您甚至可能希望添加另一个非vanilla SomeClass bean,如下所示:

    @Bean
    SomeClass strawberryClass(){
        return new SomeClass(new Integer(1));
    }
    
  • 11
    • @component及其特化(@ Controller,@ service,@存储库)允许使用类路径扫描进行自动检测 . 如果我们看到像@Controller这样的组件类,@ service,@ update将由spring框架使用组件扫描自动扫描 .
      另一方面,

    • @Bean只能用于在配置类中显式声明单个bean .

    • @Bean用于显式声明单个bean,而不是让spring自动执行 . 它从类定义中创建bean的septate声明 .

    • 简而言之,@ Controller,@ service,@存储库用于自动检测,@ Bean用于从类创建seprate bean

    - @Controller
        public class LoginController 
        { --code-- }
    
        - @Configuration
        public class AppConfig {
        @Bean
        public SessionFactory sessionFactory() 
        {--code-- }
    

相关问题