@profile
以数据源为例,项目开发部署过程中需要切换环境,就需要调整对应的配置,此时@Profile注解就显得越发强大.
首先是主配置类
package com.my.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
* 模拟动态使用数据源 开发/测试/生产环境
* @Porfile 指定组件在哪个环境下才能被注册到容器中,不指定任何环境都能注册这个组件,默认值是"default"
*
*/
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
private StringValueResolver stringValueResolver;
private String dbDriverClass;
@Profile("dev")
@Bean
public DataSource devDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/cseplatform");
comboPooledDataSource.setDriverClass(dbDriverClass);
return comboPooledDataSource;
}
@Profile("test")
@Bean
public DataSource testDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/cseplatform");
comboPooledDataSource.setDriverClass(dbDriverClass);
return comboPooledDataSource;
}
@Profile("prod")
@Bean
public DataSource prodDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/cseplatform");
comboPooledDataSource.setDriverClass(dbDriverClass);
return comboPooledDataSource;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.dbDriverClass = resolver.resolveStringValue("db.driverclass");
}
}
其次是配置文件dbconfig.properties
然后是测试类
package com.my.test;
import com.my.config.MainConfigOfProfile;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ProfileTest {
@SuppressWarnings("resource")
@Test
public void test01(){
// ioc容器创建完成,获取ioc容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
// 获取容器中定义的所有的组件名
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for(String beanDefinitionName : beanDefinitionNames){
System.out.println(beanDefinitionName);
}
}
}
代码全了,但是如何切换当前环境呢?
有两种方式:
一种是增加虚拟机的启动参数-Dspring.profiles.active=test,表示测试环境,此时用的是测试环境的数据源如图
结果显示,testDataSource被注册进容器
另外一种就是在代码层面设置环境,只需要修改测试类
@Test
public void test02(){
// 创建ioc容器,用无参构造
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
// 设置要激活的环境,入参是可变长度参数,可以一个,可以多个
annotationConfigApplicationContext.getEnvironment().setActiveProfiles("dev","test");
// 注册主配置类
annotationConfigApplicationContext.register(MainConfigOfProfile.class);
// 启动刷新容器
annotationConfigApplicationContext.refresh();
// 获取容器中定义的所有的组件名
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for(String beanDefinitionName : beanDefinitionNames){
System.out.println(beanDefinitionName);
}
}
结果显示