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();

posted @ 2019-04-14 23:30  西班牙乞丐  阅读(6518)  评论(0编辑  收藏  举报