Java 如何创建需要动态参数的对象
从我使用spring的第一天起,我总是有一个问题。如果一个类有一个需要两个参数的构造函数,但这两个参数不是固定的,它们是根据输入请求生成的,每次它们都不同,但我需要spring容器来管理该类的实例,如何在spring中实现这一点? 比如说Java 如何创建需要动态参数的对象,java,spring,Java,Spring,从我使用spring的第一天起,我总是有一个问题。如果一个类有一个需要两个参数的构造函数,但这两个参数不是固定的,它们是根据输入请求生成的,每次它们都不同,但我需要spring容器来管理该类的实例,如何在spring中实现这一点? 比如说 Class A{ A(int x,int y){//omit} } 但是x和y不是固定的,我们需要通过我们的程序计算x和y,然后我们可以用普通java代码为A创建实例,如下所示 int x=calculate(request);
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管理的类
它们是根据输入请求生成的,每次都不同,但我需要spring容器来管理类的实例,如何在spring中实现这一点
你没有。您需要实例化以响应用户输入的类并不意味着由Spring管理
仅仅因为您使用Spring管理一些bean,并不意味着所有bean/类都应该由Spring管理。也许您必须将构造函数更改为:
Class A{
A(Request request){ this.x=calculate(request); ....}
}
我假设
int
可以被某个对象
实例替换。实现这一点的一种方法是使用该特性自定义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
s,它们是A
的依赖项的工厂,那么每次调用AFactory#getObject()
,实际上,您将收到一个a
的新实例,该实例使用其所需依赖项的新实例。您可以尝试在BeanFactory类中使用此方法(由ApplicationContext扩展)
对象getBean(字符串名、对象…参数)抛出BeansException
就你而言:
getBean(“A”,x,y)
其中“A”是类A的bean名称。您希望将springbean定义为
原型,而不是单例。这样,在每个新请求上,您的Spring上下文将创建一个新的bean实例
在Java配置中,它将如下所示:
@Scope(“prototype”)@Bean public-MyBean-MyBean(){…}
在xml中:
…
还有一些作用域可以绑定到HTTP会话。见:
而且,正如其他人指出的,您必须为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){}
}
请参阅:
- 最简单的方法是使用
ApplicationContext.getBean(字符串名称、对象…参数)
-它可以创建一个原型
-作用域bean,将给定的参数传递给它的构造函数。显然,在任何使用a
的bean中直接使用ApplicationContext
不是一个好主意
- 更优雅的方法是将
A
的创建隐藏在工厂后面。该工厂可以在内部使用前面的方法,也可以以常规方式获取bean的实例(Provider,它允许Spring初始化使用new
创建的对象)。尽管它需要一些额外的运行时环境配置
为什么您希望spring管理这些实例?在一个由spring容器管理的类中是否有成员?是的,我忘了指出类A依赖于由spring容器管理的其他一些类。不同意。海报是询问如何使用spring,而不是他是否应该使用spring。S支持每个用户请求beanspring的scope=“request”
属性。@noahz是正确的,我需要所有bean都由spring管理,因为有依赖项需要由spring管理,我认为如果我们使用spring,但仍然使用new,我认为这不是一个好主意。我认为第一点是公平的,但第二点是公平的“如果我们使用spring,但仍然使用new,我认为这不是一个好主意”似乎是一个危险的想法。