spring切换环境变量——@Profile注解的使用
在容器中如果存在同一类型的多个组件,也可以使用@Profile注解标识要获取的是哪一个bean,这在不同的环境使用不同的变量的情景特别有用。例如,开发环境、测试环境、生产环境使用不同的数据源,在不改变代码的情况下,可以使用这个注解来切换要连接的数据库。
步骤如下:
1. 在bean上加@Profile注解,其value属性值为环境标识,可以自定义;
2. 使用无参构造方法创建容器
3. 设置容器环境,其值为第1步设置的环境标识
4. 设置容器的配置类
5. 刷新容器
注:2、4、5步其实是带参构造方法的步骤,相当于把带参构造方法拆开,在其中插入一条语句设置容器环境,详spring源码
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }
以下是在不同环境下不同的数据源组件的示例
/** * 容器配置类 * 用于测试@Profile注解 */ @Configuration @PropertySource(value = {"classpath:/dbconfig.properties"}) public class ProfileBeanConfig implements EmbeddedValueResolverAware { //数据库连接用户名 @Value(value = "${jdbc.username}") private String username; //数据库连接密码 private String password; //开发环境数据源 @Bean(value = "dataSourceDev") @Profile(value = "dev") public DataSource dataSourceDev(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev"); return comboPooledDataSource; } //测试环境数据源 @Bean(value = "dataSourceTest") @Profile("test") public DataSource dataSourceTest(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); return comboPooledDataSource; } //生产环境数据源 @Bean(value = "dataSourceProduction") @Profile("production") public DataSource dataSourceProduction(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/production"); return comboPooledDataSource; } //获取字符串解析器 @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { //解析配置文件,然后对数据库连接密码进行赋值 this.password = resolver.resolveStringValue("jdbc.password"); } }
以下是切换数据源示例
//创建匿名容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); //设置环境,其值为@Profile注解的属性值 applicationContext.getEnvironment().setActiveProfiles("test"); //注册容器类 applicationContext.register(ProfileBeanConfig.class); //刷新容器 applicationContext.refresh();