如何使用运行时参数创建原型范围的@Bean?使用getBean(String name,Object ... args)?

时间:2018-05-25 21:00:00

标签: java spring dependency-injection inversion-of-control spring-ioc

如何使用运行时参数创建原型范围的@Bean?使用getBean(String name, Object... args)? 我的问题是 this question

的结果

为什么Spring IoC documentation中未使用或提及此方法?

这是正常方法吗?是否有更正确的方法用于创建具有运行时参数的原型@Bean?

如果正常方法,你能解释一下原因吗? 注意,我需要通过构造函数设置我的参数,通过setter。

@Autowired
private ApplicationContext appCtx;

public void onRequest(Request request) {
    //request is already validated
    String name = request.getParameter("name");
    Thing thing = appCtx.getBean(Thing.class, name);

    //System.out.println(thing.getName()); //prints name
}

-

public class Thing {

    private final String name;

    @Autowired
    private SomeComponent someComponent;

    @Autowired
    private AnotherComponent anotherComponent;

    public Thing(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

2 个答案:

答案 0 :(得分:0)

在构造函数注入方面,没有。但是,您可以Thing init方法并使用ObjectFactory

@Autowired
private ObjectFactory<Thing> thingFactory;

public void onRequest(Request request) {
    //request is already validated
    Thing thing = thingFactory.getObject();
    thing.init("name");

    //System.out.println(thing.getName()); //prints name
}

事情是:

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

    private String name;

    @Autowired
    private SomeComponent someComponent;

    @Autowired
    private AnotherComponent anotherComponent;

    public init(String name) {
        this.name = name;
    }

}

不幸的是,name不能final,因为它不是通过构造函数。很想知道是否有更好的方法可以使用constructor injection

答案 1 :(得分:0)

可以在豆工厂的帮助下:

@Configuration
public class ThingProvider {

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Thing create(String name) {
        return new Thing(name);
    }

}

用法:

@Component
public class SomeBean {

    @Autowired
    private ThingProvider thingProvider;

    public void onRequest(Request request) {

        String name = request.getParameter("name");
        Thing thing = myProvider.create(name);
    }

}

作为反对appCtx.getBean(Thing.class, name)的论据,经常提出的是它需要硬连接Spring特定的类。另外,如果Thing构造函数发生更改,则不会进行编译时检查。