Spring 3:注入默认Bean,除非存在另一个Bean [英] Spring 3: Inject Default Bean Unless Another Bean Present

查看:153
本文介绍了Spring 3:注入默认Bean,除非存在另一个Bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过XML配置Spring,如果存在特定的bean,它将被注入目标bean。如果它不存在,将注入一个不同的默认bean。

I would like to configure Spring via XML such that if a particular bean exists, it will be injected into the target bean. If it does not exist, a different, default bean, will be injected.

例如,如果我有这样的文件

For example if I have a file like this

<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 注入司机。但是,如果我还加载以下文件:

And load it, I would like the defaultCar injected into the driver. However, if I also load the following file:

<bean id="customCar" class="FlyingCar">
  <property name="name" value="Rocket Car"/>
  <property name="maxAltitude" value="80000"/>
</bean>

我希望 customCar bean成为用来代替 defaultCar bean。我最初的尝试不起作用,但我认为说明了我想要实现的目标:

I would want the customCar bean to be used instead of the defaultCar bean. My initial attempt does not work, but I think illustrates what I'm trying to achieve:

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

我知道如何使用 PropertyPlaceholderConfigurer ,但除了包含自定义bean的文件之外,我不想提供属性文件/ VM属性/环境变量/等。谢谢!

I know how to do this with a PropertyPlaceholderConfigurer, but I don't want to have to provide a property file / VM property / environment variable / etc. in addition to the file that contains the custom bean. Thanks!

更新:

基于使用一个工厂豆评论,我调查了这个,并提出了以下解决方案。首先,我创建了一个通用工厂bean,允许您指定默认bean名称和覆盖bean名称:

Based on the "use a factory bean" comments, I looked into this and came up with the following solution. First, I created a generic factory bean that allows you to specify a default bean name and an override bean name:

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

要配置我的示例汽车司机,你可以这样做:

To configure my example car driver, you would do this:

<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,但这样可行。也许添加一个自定义架构元素可以使它变得更干净。

I would have preferred to use SpEL, but this works. Perhaps adding a custom schema element woud make this cleaner.

赞赏其他评论。

推荐答案

使用FactoryBean是最简单的解决方案 - 您可以描述您想要的任何算法。
更多信息来自

Using FactoryBean is the simplest solution - you can describe any algorithm you want. More information is at

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/FactoryBean.html

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-extension-factorybean

这篇关于Spring 3:注入默认Bean,除非存在另一个Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆