我知道在spring 2.5中引入@Component注释是为了通过使用类路径扫描来摆脱xml bean定义。

@Bean是在spring 3.0中引入的,可以和@Configuration一起使用,以便完全摆脱xml文件,而使用java配置。

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


当前回答

创建@Bean是为了避免在编译时耦合Spring和业务规则。这意味着您可以在其他框架(如PlayFramework或JEE)中重用业务规则。

此外,在默认的Spring实例化还不够的情况下,您可以完全控制如何创建bean。

我写了一篇关于它的文章。

https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/

其他回答

@ component 适用于元件扫描和自动布线。

什么时候应该使用@Bean?

有时自动配置不是一个选项。什么时候?让我们想象一下,您想要连接来自第三方库的组件(您没有源代码,所以不能用@Component注释它的类),因此自动配置是不可能的。

@Bean注释返回一个对象,spring应该在应用程序上下文中将该对象注册为bean。方法主体承担负责创建实例的逻辑。

假设我想要特定的实现依赖于某种动态状态。 @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没有办法做到这一点。

@Bean可以有作用域,而@component不能 如 @Scope(value = WebApplicationContext.)SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)

创建@Bean是为了避免在编译时耦合Spring和业务规则。这意味着您可以在其他框架(如PlayFramework或JEE)中重用业务规则。

此外,在默认的Spring实例化还不够的情况下,您可以完全控制如何创建bean。

我写了一篇关于它的文章。

https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/

您可以使用@Bean使现有的第三方类对Spring框架应用程序上下文可用。

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}

通过使用@Bean注释,您可以将第三方类(它可能没有@Component,也可能不使用Spring)包装为Spring bean。然后,一旦使用@Bean包装它,它就是一个单例对象,可以在Spring框架应用程序上下文中使用。现在,您可以使用依赖注入和@Autowired在应用程序中轻松地共享/重用此bean。

因此,可以将@Bean注释看作第三方类的包装器/适配器。您希望使第三方类对Spring框架应用程序上下文可用。

通过在上面的代码中使用@Bean,我显式地声明了一个bean,因为在方法内部,我使用new关键字显式地创建了对象。我还手动调用给定类的setter方法。所以我可以改变前缀字段的值。所以这种手工工作被称为显式创建。如果我对同一个类使用@Component,那么在Spring容器中注册的bean的前缀字段将具有默认值。

另一方面,当我们用@Component注释一个类时,我们不需要手动使用new关键字。它由Spring自动处理。