Spring 3: Внедрить компонент по умолчанию, если не присутствует другой компонент

Я хотел бы настроить 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>

, я бы хотел, чтобы bean-компонент customCar использовался вместо bean-компонента defaultCar . Моя первая попытка не сработала, но я думаю, это иллюстрирует то, чего я пытаюсь достичь:

<bean id="carDriver" class="Driver">
  <property name="car" value="#{ @customCar eq null ? 'defaultCar' : 'customCar' }"/>
</bean>

Я знаю, как это сделать с помощью PropertyPlaceholderConfigurer , но я не хочу предоставлять файл свойств / свойство виртуальной машины / переменную среды / т. Д. В дополнение к файлу, содержащему настраиваемый фасоль. Спасибо!


Обновление:

Основываясь на комментариях «использовать фабричный компонент», я изучил это и придумал следующее решение. Во-первых, я создал общий заводской компонент, который позволяет вам указать имя компонента по умолчанию и имя переопределенного компонента:

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, но это работает. Возможно, добавление настраиваемого элемента схемы сделает это чище.

Дополнительные комментарии приветствуются.

15
задан SingleShot 29 March 2011 в 16:41
поделиться