如果我有这样的课程:
@Service
@Scope("prototype")
public class TraderStarter {
private String address;
}
和TraderStarter应该创建X次,X由数据库动态确定。我应该如何获得这些豆子? 只有这样吗?
@Component("SpringContextUtil")
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
return (T) applicationContext.getBean(name);
}
}
使用SpringContextUtil .getBean()并为每个原型TraderStarter设置参数? 非常感谢。
答案 0 :(得分:1)
因此,如果您想创建这些原型bean,则有人会触发此过程。
当然,一种方法是使用ApplicationContext
,但是IMO是一种不好的方法,因为您的代码已与spring耦合。
您不能将原型注入到单例中,这是行不通的。
但是,您可以使用与Spring集成的javax.inject.Provider
接口:
这里是一个例子:
// from your example
// you can use injection here and everything, its a regular spring bean
@Service
@Scope("prototype")
public class TraderStarter {
private String address;
public void setAddress(String address) {
this.address = address;
}
}
///////////////////////
@Component
public class MyDbManager {
private Provider<TraderStarter> traderStarterProvider;
public List<TraderStarter> dynamicallyCreateBeans() {
List<String> addresses = dbManager.findAllAddresses();// to to the db, get the data
return
addresses.stream()
.map(this::createTraderStarter) // <-- creates different beans!
.collect(Collectors.toList());
}
private TraderStarter createTraderStarter(String address) {
TraderStarter ts = provider.get();
ts.setAddress(address);
return ts;
}
}
工厂还有其他方法(请参阅ObjectFactory)和创建代理(查找方法和作用域代理),但是IMO这是最干净的方法。
无论如何,如果您选择其他解决方案,请阅读this tutorial