How to collect and inject all beans of a given type in Spring XML configuration

前端 未结 3 1240
时光说笑
时光说笑 2020-12-01 08:17

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 mecha

相关标签:
3条回答
  • 2020-12-01 08:23

    Old question and in Spring 3.1 it is possible:

    public class PluginPrototypeTest extends ASpringWebTest {
      @Autowired
      Collection<IDummyRepo> repos;
    
      @Test
      public void cacheTest() {
        assertNotNull(repos);
        assertEquals(2, repos.size());
        for(IDummyRepo r: repos){
          System.out.println(r.getName());
        }
      }
    }
    
    @Repository
    public class DummyRepo implements IDummyRepo {
      @Override
      public String getName(){
        return "DummyRepo";
      }
    }
    @Repository
    public class DummyRepo2 implements IDummyRepo {
      @Override
      public String getName(){
        return "DummyRepo2";
      }
    }
    
    0 讨论(0)
  • 2020-12-01 08:45

    Alternative to @Autowired, using a context file: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-autowire

    So you'd have:

    <bean class="MenuManagementBean" autowire="byType" />
    

    Other properties can be specified, as normal, and that would override the autowiring only for those properties.

    0 讨论(0)
  • 2020-12-01 08:49

    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;
        }    
    }
    

    and then

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

    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.

    0 讨论(0)
提交回复
热议问题