[英]Spring Java Config: how do you create a prototype-scoped @Bean with runtime arguments?
[英]How do you create a prototype-scoped @Bean with runtime arguments? With getBean(String name, Object... args)?
如何使用运行时参数创建原型范围的@Bean? 使用getBean(String name, Object... args)
? 我的问题是这个问题的结果。
为什么Spring IoC 文档中没有使用或提到这种方法?
这是正常的方法吗? 是否有更正确的方法来创建带有运行时参数的原型 @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;
}
}
在构造函数注入方面,没有。 但是,您可以为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
name
因为它不是通过构造函数生成的。 很想看看是否有更好的方法可以通过constructor injection
。
可以在bean工厂的帮助下进行:
@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)
的参数而appCtx.getBean(Thing.class, name)
是,它需要硬连接Spring特定的类。 另外,万一Thing
构造函数发生变化,也没有编译时间检查。
在这种情况下,您的Thing
类可能会混合构造函数依赖项和运行时参数,如下所示:
public class Thing {
private final SomeComponent someComponent;
private final AnotherComponent anotherComponent;
private final String name;
@Autowired
public Thing(SomeComponent someComponent,
AnotherComponent anotherComponent,
String name) {
this.someComponent = someComponent;
this.anotherComponent = anotherComponent;
this.name = name;
}
public String getName() {
return this.name;
}
}
然后你可以将它们包装在配置中:
@Configuration
public class BeanConfig {
@Autowired
private SomeComponent someComponent;
@Autowired
private final AnotherComponent anotherComponent;
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Thing createThing(String name) {
return new Thing(someComponent, anotherComponent, name);
}
}
用法:
@Autowired
private BeanFactory beanFactory;
public void onRequest(Request request) {
String name = request.getParameter("name");
Thing thing = beanFactory.getBean(Thing.class, name);
}
它应该可以工作,但不确定这是否是一个好习惯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.