从使用春天的第一天起,我总是有一个问题。如果一个类有一个需要两个参数的构造函数,但是这两个参数没有修复,它们是根据输入请求生成的,每次它们都不同,但是我需要spring容器来管理类的实例,如何在春天实现这个? 例如
Class A{
A(int x,int y){//omit}
}
但是x和y不是固定的,我们需要通过程序计算x和y,然后我们可以在普通的java代码中为A创建实例,如下所示
int x=calculate(request);
int y=calculate(request);
A a=new A(x,y);
但是如何让spring管理A类的实例创建?
附加信息:为什么我需要A级由spring管理,因为A依赖于其他一些由spring管理的类。
答案 0 :(得分:7)
最简单的方法是使用ApplicationContext.getBean(String name, Object... args)
- 它可以创建一个prototype
范围的bean,将给定的参数传递给它的构造函数。显然,在使用ApplicationContext
的任何bean中直接使用A
并不是一个好主意。
更优雅的方法是隐藏工厂后面A
的创建。该工厂可以在内部使用以前的方法,或者它可以以常规方式(Provider<A>
等)获取bean的实例,然后调用非public
初始化方法来传递该参数(而不是通过使用构造函数传递参数)。
另一个应用是使用@Configurable
and load-time weaving允许Spring初始化使用new
创建的对象。虽然它需要一些额外的运行时环境配置。
答案 1 :(得分:2)
它们是根据输入请求生成的,每次都不同,但是我需要spring容器来管理类的实例,如何在spring中实现呢?
你没有。您需要实例化以响应用户输入的类不是由Spring管理的。
仅仅因为您使用Spring来管理某些bean,并不意味着所有bean / classes 应该由Spring管理。
答案 2 :(得分:1)
您希望将Spring Bean定义为prototype
而不是singleton
。这样,在每个新请求中,您的Spring上下文将创建一个新的bean实例。
在Java配置中,它看起来像这样:
@Scope("prototype") @Bean public MyBean myBean() { ... }
在xml中:
<bean id="myBean" class="whatever.MyBean" scope="prototype"> ...
还有一些范围可以绑定到HTTP会话。参见:
http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html
而且,正如其他人指出的那样,你必须为你的bean定义一个工厂方法:
请参阅:Spring and passing parameters to factory-method in runtime
答案 3 :(得分:0)
也许您必须将构造函数更改为:
Class A{
A(Request request){ this.x=calculate(request); ....}
}
答案 4 :(得分:0)
我假设某个int
实例可以替换Object
。实现此目的的一种方法是使用Spring's FactoryBean功能来自定义bean的初始化:
class AFactory implements o.s.b.f.FactoryBean {
private SomeObject firstParam;
private OtherObject secondParam;
public Object getObject() {
return new A(firstParam, secondParam);
}
public Class getObjectType() {
return A.class;
}
public boolean isSingleton() {
return false;
// i.e. every time #getObject() is called a new instance is created === prototype scope
}
public void setFirstParam(SomeObject firstParam){}
public void setSecondParam(OtherObject secondParam){}
}
注意,如果SomeObject
和OtherObject
实际上是FactorBean
的依赖关系工厂的其他A
,那么每次调用AFactory#getObject()
时,您实际上会收到A
的新实例,该实例使用其所需依赖项的新实例。
答案 5 :(得分:0)
您可以尝试在BeanFactory类中使用此方法(由ApplicationContext扩展)
Object getBean(String name,Object ... args)抛出BeansException;
在你的情况下: context.getBean(“A”,x,y);
其中“A”是A类的bean名称。