Один из самых сильных диакритических знаков платформы 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
класс)?
Нет никаких готовых средств для этого, нет. Однако, если вам нужен способ собрать все бобы заданного типа в коллекцию, не используя список @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, и нет знания о том, откуда берутся опции
.
Альтернатива @Autowired, использование контекстного файла: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-autowire
Таким образом, у вас будет:
<bean class="MenuManagementBean" autowire="byType" />
Другие свойства могут быть указаны, как обычно, и это отменит автоподключение только для этих свойств.