环境和profile:(因为不同环境中所生成bean的最佳策略不相同)
所以就需要一种类似于策略模式的思想,这里的实现则是通过profile bean来实现。(介绍的两种就是基于Java配置的@Profile注解和在XML中装配profile)
Java配置:(Spring3.1中,只能在类级别上使用@Profile注解;但从Spring3.2开始,可以在方法级别上使用@Profile注解)
//方法级别上使用@Profile注解
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;
@Configuration
public class DataSourceConfig{
@Bean(destroyMethod = "shutdown")
@Profile("dev") //为dev profile装配的bean
public DataSource embeddedDatabaseBuilder(){
return new EmbeddedDatabseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
@Bean
@Profile("prov")
public DataSource jndiDataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean =
new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/myDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFactoryBean.getObject();
}
}
XML配置:(利用的profile属性,并且可以在跟元素中嵌套定义元素)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc = "http://www.springframework.org/schema/jdbc"
xmlns:jee = "http://www.springframework.org/schema/jee"
xmlns:p = "http://www.springframework.org/schema/p"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/context/spring-jdbc.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd">
<beans profile = "dev">
<jdbc:embedded-database id = "classpath:schema.sql">
<jdbc:script location = "classpath:schema.sql"/>
<jdbc:script location = "classpath:test-data.sql"/>
</jdbc:embedded-database>
</beans>
<beans profile="qa">
<bean id = "dataSource"
class = "org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:url = "jdbc:h2:tcp://dbserver/~/test"
p:driverClassName = "org.h2.Driver"
p:username = "sa"
p:password = "password"
p:initialSize = "20"
p:maxActive = "30"/>
</beans>
<beans profile="prod">
<jee:jndi-lookup id = "dataSource"
jndi-name="jdbc/myDatabase"
resource-ref="true"
proxy-interface="javax.sql.DataSource"/>
</beans>
</beans>
激活profile:(其中包括两个属性:spring.profiles.active和spring.profiles.default需要设置相应的值(有多种方式设置))
- 作为DispatcherServlet的初始化参数
- 作为web应用的上下文参数
- 作为JNDI条目
- 作为环境变量
- 作为JVM的系统属性
- 在集成测试类上,使用@ActiveProfiles注解设置
使用profile测试(在前面的方法中采用@ActiveProfiles注解,可以根据具体 环境选择要激活的profile)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceTestConfig.classes})
@ActiveProfiles("dev")
public class PersistenceTest{
...
}
总结:Spring的profile机制对于条件化创建bean是一种很不错的方法,但是Spring4.0中提供了一种更为通用的机制来实现条件化的bean定义(条件完全由自己来确定,即@Conditional注解定义条件化的bean)