java - spring:使用@Autowired和context:component-scan自动连接原型(prototype)bean时如何使用非默认构造函数?

标签 java spring

假设你有一个如下的原型(prototype) bean 类:

@Component
@Scope("prototype")
public class Foobar {
    private String foo;
    public Foobar( String foo ) {
        this.foo = foo;
    }
}

那么,是否可以使用 @Autowired 将这样的 bean 连接到另一个类中,该类应该使用非默认构造函数 Foobar(String foo) 来实例化 bean ?

更新
在上面的示例中,构造函数参数 String foo 在应用程序上下文中不可用,而是动态的。因此,使用 @Autowired 注释构造函数,然后在上下文中的某处指定 foo 似乎不是一个理想的解决方案。

最佳答案

这里有 3 种方法,只需看看最适合您情况的方法:

使用@Autowired 构造函数

更好的时候:您拥有在上下文中构建原型(prototype) bean 所需的一切(即使对于属性,例如 @Value("${prop}"))

如果您想要一种自动的方式来执行此操作,您还需要拥有在上下文中实例化 bean 所需的一切(即使对于原型(prototype) bean)。如果您在上下文中拥有所需的一切,您可以简单地将构造函数注释为 @Autowired,Spring 将为您完成其余的工作。

@Component
@Scope("prototype")
public class FooBar {

    private Baz baz;

    @Autowired
    public FooBar(Baz baz) {
        this.baz = baz;
    }

}

使用 FactoryBeans

更好的时候:如果您使用基于 XML 的上下文,您会更喜欢这种方式。

如果您需要一种个性化的方式来做这件事,另一种可能性是使用 FactoryBeans。来自 documentation :

Interface to be implemented by objects used within a BeanFactory which are themselves factories. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

FactoryBean 被 Spring 用于构建您请求的对象(无论是原型(prototype)还是单例)。

对于你的情况,你可以有这样的实现:

@Component
public class FooBarFactory implements FactoryBean<FooBar> {

    @Autowired
    private Baz myContextProvidedObject;

    @Override
    public FooBar getObject() throws Exception {
        return new FooBar(myContextProvidedObject, "my parameter");
    }

    @Override
    public Class<?> getObjectType() {
        return FooBar.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

}

您可以在上下文的其他实例上简单地 @Autowired FooBar

使用 @Configuration

更好的时候:如果您已经使用注释配置了上下文,那么您肯定会更喜欢这种方式。

第三种方法是使用你的 @Configuration 类,这是我最喜欢的。来自 documentation :

public @interface Configuration: Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example:

在该类中,您可以使用如下方法:

@Configuration
public class MyConfig {

    @Bean
    @Scope("prototype")
    public FooBar fooBar(Baz myContextProvidedObject) {
        return new FooBar(myContextProvidedObject, "my parameter");
    }

}

关于java - spring:使用@Autowired和context:component-scan自动连接原型(prototype)bean时如何使用非默认构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25232034/

相关文章:

java - 如何拥有带有创建和更新日期的枚举查找表?

java - Tomcat - 上下文初始化失败

java - 数据未插入 MySQL 数据库

java - 对同一件事执行多个 if 语句的更简单方法

java - 混合注释时 Spring MVC 拦截器停止工作

java - 如何从 OAuth2 客户端应用程序中的授权服务器获取作为访问 token 响应一部分的附加信息

Spring Boot 中数据库的 jquery 自动完成

java - 在JAVA中多次调用3D立方体绘制方法?

java - 如果注入(inject)器是 child ,Jersey-Guice 不会处理绑定(bind)资源?

java - 有没有办法使用接口(interface)在代码中注入(inject)依赖项?