【问题标题】:Creating beans on-demand using spring使用spring按需创建bean
【发布时间】:2010-01-24 19:11:32
【问题描述】:

我想在启动后以工厂模式创建一些 spring bean。例如,我经常有一些工作要做,我需要创建一个任务 bean(它可能依赖于其他单例 spring bean)并执行它。

可能有多个工作要同时执行,因此每个任务 bean 都需要是独立的(原型)。

人们有什么共同的模式来实现这一点吗?

在我看来,我需要以某种方式与 container/applicationContext 交互,但我真的不想分散 applicationContext/beanFactory 的注入和对 getBean("...") 的调用。

我想到了类似的东西(注意“工厂”是我想象的东西,而不是存在的东西)

<bean id="myTask" class="MyTask" scope="prototype">
  <property name="entityManager" ref=".../>
  ...
</bean>

<bean id="myTaskExecutor" class="MyTaskExecutor">
  <property name="taskFactory">
     <xxx:factory bean="myTask"/>
  </property>
</bean>

然后编码

class MyTaskExecutor
{
  private Factory<MyTask> taskFactory;

  public void setTaskFactory( Factory<MyTask> taskFactory )
  {
    this.taskFactory = taskFactory;
  }
}

也许还有注释版本

class MyTaskExecutor
{
  @Factory(MyTask.class)
  private Factory<MyTask> taskFactory;

}

也许上面已经有类似的东西了?还是我在某处遗漏了一些基本的东西。

我意识到我可以有一个单例 MyTaskFactory 并使用它来使用“new”进行实例化,但是我必须从工厂传递它的所有依赖项,这感觉不对。

所以我想总结的问题是

在应用程序代码中按需创建原型 Spring bean 的推荐方法是什么?

感谢任何意见。

【问题讨论】:

    标签: java spring


    【解决方案1】:

    我认为你把问题复杂化了。您需要做的就是编写一个TaskFactory 类(没有什么特别之处,没有特殊的接口或注释)。 TaskFactory 将被注入所需的所有其他 bean,并且将有一个 createTask 方法按需创建任务,并在创建新任务时将对所需 Spring bean 的引用传递给新任务。客户端代码注入TaskFactory,需要时调用createTask

    Spring 本身没有为您尝试做的事情提供明确的支持。 factory-method XML 属性和FactoryBean 接口之类的仅用于在其范围内一次性创建 bean,如果您想按需创建它们,则意味着 scope="prototype",这意味着使用 @987654330 @。

    编辑: 可能值得指出的是,原型范围的 bean 实际上并不是 Spring 的设计目标。是的,它支持它们,但使用它们并不是一种非常有启发性的体验。如果您真的想走这条路,那么值得taking a look at @Configurable。由于运行时类加载器的限制,它非常强大,但并不总是适合。

    【讨论】:

    • 我明白你在说什么,但它仍然不是一个很好的解决方案(我在上面提到过有一个工厂)。考虑一下 MyTask 是否依赖于其他原型范围的 bean,每个 bean 都有自己的依赖项。我将不得不在工厂中制造所有这些(并将它们的依赖项注入我的工厂)并将它们传递给 MyTask,或者让 MyTask 创建它们,并让工厂传递所有其他原型 bean 的依赖项。这一切都相当于不使用 spring 来处理单例,只是在这种情况下,它是用于原型作用域的 bean。
    【解决方案2】:

    我正在尝试做与此非常相似的事情(Spring 3.0),所以我很想知道您最终是如何解决这个问题的。

    我目前的方法是使用 getBean() 并且我已经使用 Spring 实例化的 beans/pojos 使用默认的单例范围。所以我现在有非线程安全的代码,但想进一步改进它以使其成为线程安全的。

    【讨论】:

    • 我最终只是在相关 bean 上使用 BeanFactoryAware 并根据需要调用 getBean() 来制造我的原型 bean。我确信注释解决方案是完全可行的,但我认为这对我来说太过分了,因为我只需要一个非常大的应用程序中大约 5-10 个位置的功能。
    猜你喜欢
    • 1970-01-01
    • 2020-01-28
    • 2015-09-07
    • 2016-10-20
    • 1970-01-01
    • 2011-03-15
    • 2017-01-13
    • 2017-11-19
    • 1970-01-01
    相关资源
    最近更新 更多