如何创建需要动态参数的对象

时间:2012-09-10 15:38:24

标签: java spring

从使用春天的第一天起,我总是有一个问题。如果一个类有一个需要两个参数的构造函数,但是这两个参数没有修复,它们是根据输入请求生成的,每次它们都不同,但是我需要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管理的类。

6 个答案:

答案 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){}

}

注意,如果SomeObjectOtherObject实际上是FactorBean的依赖关系工厂的其他A,那么每次调用AFactory#getObject()时,您实际上会收到A的新实例,该实例使用其所需依赖项的新实例。

答案 5 :(得分:0)

您可以尝试在BeanFactory类中使用此方法(由ApplicationContext扩展)

Object getBean(String name,Object ... args)抛出BeansException;

在你的情况下: context.getBean(“A”,x,y);

其中“A”是A类的bean名称。

相关问题