春季:@Component与@Bean

本文翻译自:Spring: @Component versus @Bean

I understand that @Component annotation was introduced in spring 2.5 in order to get rid of xml bean definition by using classpath scanning. 我了解到@Component注释是在Spring 2.5中引入的,目的是通过使用类路径扫描摆脱xml bean的定义。

@Bean was introduced in spring 3.0 and can be used with @Configuration in order to fully get rid of xml file and use java config instead. @Bean是在Spring 3.0中引入的,可以与@Configuration一起使用,以完全摆脱xml文件并改用Java config。

Would it have been possible to re-use the @Component annotation instead of introducing @Bean annotation? 是否有可能重新使用@Component注释而不是引入@Bean注释? My understanding is that the final goal is to create beans in both cases. 我的理解是,两种情况下的最终目标都是创建bean。


#1楼

参考:https://stackoom.com/question/iUf4/春季-Component与-Bean


#2楼

@Component and @Bean do two quite different things, and shouldn't be confused. @Component@Bean做两个完全不同的事情,不要混淆。

@Component (and @Service and @Repository ) are used to auto-detect and auto-configure beans using classpath scanning. @Component (以及@Service@Repository )用于使用类路径扫描自动检测和自动配置bean。 There's an implicit one-to-one mapping between the annotated class and the bean (ie one bean per class). 在带注释的类和Bean之间存在隐式的一对一映射(即,每个类一个Bean)。 Control of wiring is quite limited with this approach, since it's purely declarative. 由于此布线仅是声明性的,因此使用此方法对布线的控制非常有限。

@Bean is used to explicitly declare a single bean, rather than letting Spring do it automatically as above. @Bean用于显式声明单个bean,而不是像上面那样让Spring自动执行。 It decouples the declaration of the bean from the class definition, and lets you create and configure beans exactly how you choose. 它使Bean的声明与类定义脱钩,并让您完全按照自己的选择创建和配置Bean。

To answer your question... 要回答您的问题...

would it have been possible to re-use the @Component annotation instead of introducing @Bean annotation? 是否有可能重新使用@Component注释而不是引入@Bean注释?

Sure, probably; 当然可以; but they chose not to, since the two are quite different. 但他们选择不这样做,因为两者是完全不同的。 Spring's already confusing enough without muddying the waters further. 春天已经足够混乱了,又没有使水进一步混乱。


#3楼

Let's consider I want specific implementation depending on some dynamic state. 让我们考虑根据某些动态状态来实现特定的实现。 @Bean is perfect for that case. @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();
    }
}

However there is no way to do that with @Component . 但是,无法使用@Component做到这一点。


#4楼

@Component Preferable for component scanning and automatic wiring. @Component优选用于组件扫描和自动接线。

When should you use @Bean ? 什么时候应该使用@Bean

Sometimes automatic configuration is not an option. 有时,自动配置不是一个选择。 When? 什么时候? Let's imagine that you want to wire components from 3rd-party libraries (you don't have the source code so you can't annotate its classes with @Component), so automatic configuration is not possible. 假设您想从第三方库连接组件(您没有源代码,因此不能使用@Component注释其类),因此无法进行自动配置。

The @Bean annotation returns an object that spring should register as bean in application context. @Bean批注返回一个对象该对象应在应用程序上下文中作为Spring注册为bean。 The body of the method bears the logic responsible for creating the instance. 方法主体具有负责创建实例的逻辑。


#5楼

Both approaches aim to register target type in Spring container. 两种方法都旨在在Spring容器中注册目标类型。

The difference is that @Bean is applicable to methods , whereas @Component is applicable to types . 不同之处在于@Bean适用于方法 ,而@Component适用于类型

Therefore when you use @Bean annotation you control instance creation logic in method's body (see example above ). 因此,当您使用@Bean批注时,您可以控制方法主体中的实例创建逻辑(请参见上面的示例 )。 With @Component annotation you cannot. 使用@Component注释不能。


#6楼

When you use the @Component tag, it's the same as having a POJO (Plain Old Java Object) with a vanilla bean declaration method (annotated with @Bean ). 当您使用@Component标记时,它与使用香草豆声​​明方法(以@Bean注释)的POJO(普通的旧Java对象) @Bean For example, the following method 1 and 2 will give the same result. 例如,下面的方法1和2将给出相同的结果。

Method 1 方法1

@Component
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

with a bean for 'theNumber': 与“ theNumber”的bean:

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

with the beans for both: 与两个豆:

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

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

Method 2 allows you to keep bean declarations together, it's a bit more flexible etc. You may even want to add another non-vanilla SomeClass bean like the following: 方法2允许您将bean声明保持在一起,这更加灵活等等。您甚至可能想要添加另一个非香草的SomeClass bean,如下所示:

@Bean
SomeClass strawberryClass(){
    return new SomeClass(new Integer(1));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值