0

我们如何使用布尔值在 Spring Context XML 中的不同实现之间切换?例如:

<bean id="detailsController"  class="com.something.detailsController" >

如果是真的那么

<property name="dao" ref="firstDao"/>

别的

<property name="dao" ref="secoundDao"/>

我知道在 Spring3 中我们可以使用配置文件

4

5 回答 5

0

您可以通过修改 Java 代码并将 Spring EL 与ApplicationAware和一起使用来做到这一点InitializingBean

public class DetailsController implements ApplicationContextAware, InitializingBean {

    private DetailsControllerDAO dao;

    private String daoName;

    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void afterPropertiesSet() {
        dao = applicationContext.getBean(daoName);
    }

    public void setDaoName(String daoName) {
        this.daoName = daoName;
    }

}

在 XML 中:

<bean id="detailsController" class="com.something.detailsController">
    <property name="daoName" value="#{myCondition ? 'firstDao' : 'secondDao'}" />
</bean>

当然,这种解决方案的缺点是在控制器中添加对 Spring 代码的依赖。为避免这种情况,您可以在代理类中移动该代码,如 Guillaume Darmont 所述。

于 2013-06-18T21:52:02.590 回答
0

由于您的 DAO 是可交换的,因此它们继承了相同的类型(抽象类或接口)。因此,您可以编写一个RoutingDetailsControllerDAO.

假设您的公共接口名为DetailsControllerDAO,有两个方法getDetailsgetMoreDetails在里面,代码是:

public class RoutingDetailsControllerDAO implements DetailsControllerDAO {
    private DetailsControllerDAO firstDAO;
    private DetailsControllerDAO secondDAO;

    protected DetailsControllerDAO getDAOToUse() {
       return YOUR_BOOLEAN_CONDITION ? firstDAO : secondDAO;
    }

    @Override
    public Details getDetails() {
       return getDAOToUse().getDetails();
    }

    @Override
    public Details getMoreDetails() {
       return getDAOToUse().getMoreDetails();
    }

    // Insert firstDAO and secondDAO setters below
    ...

}

您的 Spring XML 配置现在是:

<bean id="detailsController" class="com.something.detailsController" >
   <property name="dao" ref="routingDetailsControllerDAO"/>
</bean>
<bean id="routingDetailsControllerDAO" class="com.something.RoutingDetailsControllerDAO">
   <property name="firstDao" ref="firstDao"/>
   <property name="secondDao" ref="secondDao"/>
</bean>
于 2013-06-18T21:34:46.110 回答
0

几种可能:

  • 您可以使用配置文件 ( <beans profiles="profileOne">)。
  • 您可以使用它FactoryBean来创建正确的 DAO
  • 您可以使用 SPeL

最后一个是最简单的:

<bean id="detailsController" class="com.something.detailsController">
    <property name="dao" ref="#{condition ? 'firstDao' : 'secondDao'}" />
</bean>

当然,您可以通过属性配置器从属性文件中加载 bean 名称:

<bean id="detailsController" class="com.something.detailsController">
    <property name="dao" ref="${bean.name.from.properties.file}" />
</bean>
于 2013-06-18T22:04:07.573 回答
0

我不认为这可以在 XML 级别完成。

于 2013-06-18T14:36:18.670 回答
0

Spring 真的做不到。查看 bean 生命周期。创建了类,注入了属性,然后调用了 afterPropertiesSet() 或 @PostConstructor 方法。当然,当我省略惰性初始化 bean 时。

但是,如果您想进行测试等,因此您的应用程序中只需要 firstDao 或 secondDao,这取决于您的设置,您可以使用 bean 工厂。bean 工厂根据需要创建您的 bean。我也用它来分割开发环境、测试环境和生产环境。

package com.dummyexample.config;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 *  Factory bean to create real or test dao.
 *  The result depends on realDaoEnabled configuration parameter.
 * 
 * @author Martin Strejc
 */
@Configuration
public class DaoBeanFactory {


    // mapping to servlet context configuration
    @Resource(mappedName = "realDaoEnabled")
    private Boolean realDaoEnabled = true;

    // TestDao extends or implements Dao
    @Autowired
    private TestDao testDao;

    // ProdDao extends or implements Dao
    @Autowired
    private ProdDao prodDao;

    public DaoBeanFactory() {
    }

    @Bean(name="dao")
    public Dao getDao() {
        if(realDaoEnabled) {
            return prodDao;
        }
        return testDao;
    }


}
于 2013-06-18T20:55:35.133 回答