Я хотел бы настроить Spring через XML таким образом, что если существует конкретный bean, он будет введен в целевой bean. Если он не существует, будет введен другой, по умолчанию bean.
Например, если у меня есть такой файл
<bean id="carDriver" class="Driver">
<property name="car" value="SOME EXPRESSION GOES HERE, SEE ATTEMPT BELOW"/>
</bean>
<bead id="defaultCar" class="Car">
<property name="name" value="Honda Accord"/>
</bean>
И загрузите его, я бы хотел, чтобы defaultCar
был введен в драйвер. Однако, если я также загружаю следующий файл:
<bean id="customCar" class="FlyingCar">
<property name="name" value="Rocket Car"/>
<property name="maxAltitude" value="80000"/>
</bean>
Я хотел бы использовать customCar
bean вместо defaultCar
bean. Моя первоначальная попытка не работает, но я думаю, что иллюстрирует то, что я пытаюсь достичь:
<bean id="carDriver" class="Driver">
<property name="car" value="#{ @customCar eq null ? 'defaultCar' : 'customCar' }"/>
</bean>
Я знаю, как это сделать с помощью PropertyPlaceholderConfigurer
, но я не хочу предоставлять файл свойств/свойства VM/переменную среды/т.д. в дополнение к файлу, который содержит пользовательский bean. Спасибо!
Update:
Исходя из комментариев "use a factory bean", я рассмотрел это и придумал следующее решение. Во-первых, я создал общий factory bean, который позволяет указать имя по умолчанию bean и переопределить bean имя:
public class DefaultOverrideFactoryBean implements FactoryBean, BeanFactoryAware {
public Object getObject() throws Exception {
return beanFactory.containsBean(overrideBeanName) ?
beanFactory.getBean(overrideBeanName) :
beanFactory.getBean(defaultBeanName);
}
public Class<?> getObjectType() {
return Object.class;
}
public boolean isSingleton() {
return true;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void setDefaultBeanName(String defaultBeanName) {
this.defaultBeanName = defaultBeanName;
}
public void setOverrideBeanName(String overrideBeanName) {
this.overrideBeanName = overrideBeanName;
}
private String defaultBeanName;
private String overrideBeanName;
private BeanFactory beanFactory;
}
Чтобы настроить драйвер для моего примера, вы бы сделали следующее:
<bean id="carDriver" class="Driver">
<property name="car">
<bean class="DefaultOverrideFactoryBean">
<property name="defaultBeanName" value="defaultCar"/>
<property name="overrideBeanName" value="customCar"/>
</bean>
</property>
</bean>
Я бы предпочел использовать SpEL, но это работает. Возможно, добавление пользовательского элемента схемы woud сделает этот чист.
Дополнительные комментарии оценены.