在Spring中将原型​​列表注入Singleton bean

时间:2016-09-30 22:08:14

标签: java spring dependency-injection

春天需要一些帮助。 在我们的项目中,我们使用XML和注释配置(Spring 4.1) 最近我遇到了以下任务:

我有一个范围原型的bean列表,它们都实现了相同的接口。

此外,我还有一个具有execute方法的单例bean。在方法内部,bean应该访问那些原型bean的列表。

每次执行'execute'方法时,我都希望能够访问这些原型bean的不同实例。 在单例中我没有预先知道的整个bean列表,所以我只是@Autowire整个集合,以便加载应用程序上下文中已知的每个bean实现。

interface SomeInterface {

}


class PrototypeBean1 implements SomeInterface {
  ...
}

class PrototypeBean2 implements SomeInterface {
  ...
}


class MySingletonBean {

   @Autowire (????)
   List<SomeInterface> allPrototypeBeansLoadedIntoTheApplicationContext;

   public void execute() {
      // this one is called many times,
      // so I would like to get different lists of    
      //"allPrototypeBeansLoadedIntoTheApplicationContext"
      // with different actuals bean upon every invocation
      // how do I achieve this???
   }

} 

所以我的问题是:实现这一目标的最简洁方法是什么?理想情况下,我希望得到一个完全脱离spring接口的解决方案(比如注入ApplicationContext / BeanFactory) 我不介意在这里使用Aop(性能不是那么关键),但我无法真正地围绕一个干净的弹簧解决方案。所以任何帮助都将不胜感激。

提前致谢

1 个答案:

答案 0 :(得分:1)

我一直在尝试用Spring实现类似的目标,在使用ServiceLocatorFactoryBeanmethod injection(带 @Lookup)阅读Spring文档后,看起来很有希望。 然而,经过尝试,两种方法结果都令人沮丧。这两种方式都不支持在List中返回bean。我得到了这个例外:

  

没有'java.util.List'类型的限定bean可用

显然,Spring将返回类型视为常规对象。

所以最终我的解决方案变成了创建一个新对象来将列表包装为返回类型。

@Component
@Scope("prototype")
public class ProcessorList
{
    private List<Processor> processors;

    public ProcessorList(List<Processor> processors)
    {
        this.processors = processors;
    }

    public List<Processor> getProcessors()
    {
        return processors;
    }

    public void setProcessors(List<ChangeSetProcessor> processors)
    {
        this.processors = processors;
    }
}

然后为List Object创建一个Factory类:

@Component
public interface ProcessorFactory
{
    ProcessorList getProcessorList();
}

然后使用ServiceLocatorFactoryBean注册工厂:

@Configuration
public class MyConfiguration{
    @Bean
    public FactoryBean serviceLocatorFactoryBean()
    {
        ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
        factoryBean.setServiceLocatorInterface(ProcessorFactory.class);
        return factoryBean;
    }

}

最后实现界面并确保用@Scope(“prototype”)

标记它们

现在,每次使用工厂方法时,您都会获得新实例!

如果您愿意,它类似于使用方法注入。