Как собрать и ввести все бобы данного типа в конфигурации XML Spring

Один из самых сильных диакритических знаков платформы Spring является понятием Внедрения зависимости. Я понимаю, что один из советов позади этого состоит в том, чтобы разделить общий высокоуровневый механизм от деталей низкого уровня (как объявлено Принципом Инверсии Зависимости).

Технически, это сводится к наличию бобовой реализации для знания как можно меньше о бобе, вводимом как зависимость, например.

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


    

Но что, если я хотел к высокоуровневого механизма, воздействующего на несколько зависимых бобов?

  public class MenuManagementBean {
       private Collection

Я знаю, что одно решение состояло бы в том, чтобы использовать @Autowired аннотация в одноэлементном бобе, который является...

  @Autowired
  private Collection

Но разве это не нарушает разделительный принцип? Почему делают я должен указать, какие зависимые взять в том же самом месте я использую их (т.е. MenuManagementBean класс в моем примере)? Есть ли способ ввести наборы бобов в конфигурации XML как это (без любой аннотации в MMB класс)?


    
       
    
 

24
задан Grzegorz Oledzki 9 May 2010 в 21:45
поделиться

2 ответа

Нет никаких готовых средств для этого, нет. Однако, если вам нужен способ собрать все бобы заданного типа в коллекцию, не используя список @Autowired, то легко написать собственный FactoryBean, который сделает это за вас:

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, и нет знания о том, откуда берутся опции.

27
ответ дан 28 November 2019 в 22:34
поделиться

Альтернатива @Autowired, использование контекстного файла: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-autowire

Таким образом, у вас будет:

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

Другие свойства могут быть указаны, как обычно, и это отменит автоподключение только для этих свойств.

5
ответ дан 28 November 2019 в 22:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: