我们如何使用布尔值在 Spring Context XML 中的不同实现之间切换?例如:
<bean id="detailsController" class="com.something.detailsController" >
如果是真的那么
<property name="dao" ref="firstDao"/>
别的
<property name="dao" ref="secoundDao"/>
我知道在 Spring3 中我们可以使用配置文件
我们如何使用布尔值在 Spring Context XML 中的不同实现之间切换?例如:
<bean id="detailsController" class="com.something.detailsController" >
如果是真的那么
<property name="dao" ref="firstDao"/>
别的
<property name="dao" ref="secoundDao"/>
我知道在 Spring3 中我们可以使用配置文件
您可以通过修改 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 所述。
由于您的 DAO 是可交换的,因此它们继承了相同的类型(抽象类或接口)。因此,您可以编写一个RoutingDetailsControllerDAO
.
假设您的公共接口名为DetailsControllerDAO
,有两个方法getDetails
,getMoreDetails
在里面,代码是:
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>
几种可能:
<beans profiles="profileOne">
)。FactoryBean
来创建正确的 DAO最后一个是最简单的:
<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>
我不认为这可以在 XML 级别完成。
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;
}
}