4

从我使用 spring 的第一天开始,我总是有一个问题。如果一个类有一个构造函数需要两个参数,但是这2个参数不固定,是根据输入请求生成的,每次都不一样,但是我需要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 管理的其他类。

4

6 回答 6

7
  • 最直接的方法是使用ApplicationContext.getBean(String name, Object... args)- 它可以创建一个prototype-scoped bean,将给定的参数传递给它的构造函数。显然,ApplicationContext直接在任何使用A.

  • 更优雅的方法是将创建隐藏在A工厂后面。该工厂可以在内部使用以前的方法,或者它可以以常规方式(Provider<A>等)获取 bean 的实例,然后调用非public初始化方法来传递该参数(而不是通过使用构造函数传递参数)。

  • 另一个方法是使用@Configurable和加载时编织,它允许 Spring 初始化使用new. 虽然它需要一些额外的运行时环境配置。

于 2012-09-10T15:59:32.057 回答
2

它们是根据输入请求生成的,每次都不一样,但是我需要spring容器来管理类的实例,在spring中如何实现呢?

你没有。您需要实例化以响应用户输入的类并不意味着由 Spring 管理。

仅仅因为您使用 Spring 来管理一些 bean,并不意味着所有 bean/类都应该由 Spring 管理。

于 2012-09-10T15:50:17.570 回答
1

您希望将 Spring Bean 定义为 aprototype而不是 a 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 和在运行时将参数传递给工厂方法

于 2012-09-10T15:55:50.163 回答
0

也许您必须将构造函数更改为:

Class A{
 A(Request request){ this.x=calculate(request); ....}
}
于 2012-09-10T15:52:04.087 回答
0

我假设它int可以被某个Object实例替换。实现这一点的一种方法是使用Spring 的 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实际上可以是其他FactorBeans 的依赖项的工厂A,那么每次调用 时AFactory#getObject(),您实际上都会收到一个A使用其所需依赖项的新实例的新实例。

于 2012-09-10T15:54:08.610 回答
0

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

Object getBean(String name, Object... args) throws BeansException;

在您的情况下: context.getBean("A", x, y);

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

于 2012-09-10T15:55:17.500 回答