Spring:@Component与@Bean

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

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

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

回答(8)

3 years ago

@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 天已经足够混乱,没有进一步混淆水域 .

3 years ago

@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 承担负责创建实例的逻辑 .

3 years ago

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

3 years ago

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

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

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

3 years ago

  • @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 years ago

@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 注释的真实目的和用法 .

3 years ago

当您使用 @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));
}

3 years ago

  • @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-- }