如何在Spring XML配置中收集并注入给定类型的所有bean [英] How to collect and inject all beans of a given type in Spring XML configuration

查看:119
本文介绍了如何在Spring XML配置中收集并注入给定类型的所有bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spring框架中最强烈的一个重点是依赖注入概念。我理解背后的一个建议是将一般的高级别机制与低级细节分开(如依赖性反转原则)。

One of the strongest accents of the Spring framework is the Dependency Injection concept. I understand one of the advices behind that is to separate general high-level mechanism from low-level details (as announced by Dependency Inversion Principle).

从技术上讲,这归结为有一个bean实现尽可能少地知道一个被注入作为依赖关系的bean,例如

Technically, that boils down to having a bean implementation to know as little as possible about a bean being injected as a dependency, e.g.

public class PrintOutBean {
    private LogicBean logicBean;
    public void action() {
        System.out.println(logicBean.humanReadableDetails());
    }
    //...
}

<bean class="PrintOutBean">
    <property name="loginBean" ref="ShoppingCartBean"/>
</bean>

但是,如果我想要一个在多个依赖bean上运行的高级机制呢?

But what if I wanted to a have a high-level mechanism operating on multiple dependent beans?

  public class MenuManagementBean {
       private Collection<Option> options;
       public void printOut() {
            for (Option option:options) {
              // do something for option
            }
            //...
       }
  }

我知道一个解决方案是使用 @自动连线注释在单例bean中,即...

I know one solution would be to use @Autowired annotation in the singleton bean, that is...

  @Autowired
  private Collection<Option> options;

但是它不违反分离原则吗?为什么我必须指定在我使用它们的相同位置(即我的示例中的 MenuManagementBean 类)中的依赖关系?
有没有办法在这样的XML配置中注入bean的集合(在 MMB 类中没有任何注释)?

But doesn't it violate the separation principle? Why do I have to specify what dependents to take in the very same place I use them (i.e. MenuManagementBean class in my example)? Is there a way to inject collections of beans in the XML configuration like this (without any annotation in the MMB class)?

<bean class="MenuManagementBean">
    <property name="options">
       <xxx:autowire by-type="MyOptionImpl"/>
    </property>
 </bean>


推荐答案

没有现成的设施做这个,不行但是,如果您想要将给定类型的所有bean收集到集合中,而不使用@Autowired列表,则可以轻松地编写一个自定义的 FactoryBean 来实现对于你:

There's no out-of-the-box facility to do this, no. However, if you want a way of collecting all beans of a given type into a collection, without using an @Autowired list, then it's easy to write a custom FactoryBean to do it for you:

public class BeanListFactoryBean<T> extends AbstractFactoryBean<Collection<T>> {

    private Class<T> beanType;
    private @Autowired ListableBeanFactory beanFactory;

    @Required
    public void setBeanType(Class<T> beanType) {
        this.beanType = beanType;
    }

    @Override
    protected Collection<T> createInstance() throws Exception {
        return beanFactory.getBeansOfType(beanType).values();
    }

    @Override
    public Class<?> getObjectType() {
        return Collection.class;
    }    
}

然后

 <bean class="MenuManagementBean">
    <property name="options">
       <bean class="BeanListFactoryBean">
          <property name="beanType" class="MyOptionImpl.class"/>
       </bean>
    </property>
 </bean>

但是,这似乎都是为了避免将 @Autowired 在你的原始课。对于SoC来说,这并不是一个很大的冲突,如果是这样 - 没有compiltime依赖关系,也不知道选项来自哪里。

However, this all seems like a lot of effort to avoid putting @Autowired in your original class. It's not much of a violation of SoC, if it is at all - there's no compiltime dependency, and no knowledge of where the options are coming from.

这篇关于如何在Spring XML配置中收集并注入给定类型的所有bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆