编程修炼之spring framework条件环境

在一些场景中,有可能会遇到这种情况,在生产环境,灰度环境,开发环境和测试环境希望IOC中注入的Bean具有不同的特性。通常在paas环境中或者有配置中心的分布式开发环境,通过统一的集中配置可以完成这种需求,本篇就简单谈谈如果单单使用springframework如何实现这样的多环境配置。

@Profile

这个注解是常用的环境区分的工具。结合@Configuration,它为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。

    @Profile("default")
	@Bean("test")
	public DataSource testDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(user);
		dataSource.setPassword(password);
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}
	
	@Profile("dev")
	@Bean("dev")
	public DataSource devDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(user);
		dataSource.setPassword(password);
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}
	
	@Profile("master")
	@Bean("master")
	public DataSource masterDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(user);
		dataSource.setPassword(password);
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}

@Test
	public void test01() {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
		//1. 创建一个applicationContext
		//2. 设置需要激活的环境
		applicationContext.getEnvironment().setActiveProfiles("dev","master");
		//3. 注册主配置类
		applicationContext.register(MainConfigOfProfile.class);
		//4. 启动刷新容器
		applicationContext.refresh();
		
		String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
		System.out.println(Arrays.toString(beanNamesForType));
		
		applicationContext.close();
	}

        @Test
	public void test02() {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
		
		String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
		System.out.println(Arrays.toString(beanNamesForType));
		
		applicationContext.close();
	}

或者在测试类中

@RunWith(SpringJUnit4ClassRunner.class)//创建spring应用上下文
@ContextConfiguration(classes= DataSourceConfig.class)//加载配置类
@ActiveProfiles("dev")
public class ProfileTest {

    @Autowired
    private DataSource dataSource;

    @Test
    public void sheetTest(){
        JdbcTemplate jdbc = new JdbcTemplate(dataSource);
        List<String> query = jdbc.query("select * from customer", new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getLong("id") + ":" + rs.getString("customer_name");
            }
        });
        // [19:知识追寻者, 20:知识追寻者, 21:知识追寻者, 22:知识追寻者, 23:知识追寻者]
        System.out.println(query);
    }
}

或者Java命令中添加参数:

   -Dspring.profiles.active="profile1,profile2"

@Conditional

@Profile时间是是@Conditonal的实现。

Spring Boot除了提供通用的@Condition注解外,还提供了一些开箱即用的条件注解,方便开发者在开发时直接使用。比如:

  • ·@ConditionOnBean:在ApplicationContext中存在指定类型的Bean时启用。
  • ·@ConditionOnMissingBean:在ApplicationContext中不存在指定类型的Bean时启用。
  • ·@ConditionOnClass:在classpath下存在指定类时启用。
  • ·@ConditionOnMissingClass:在classpath下缺少指定类时启用。
  • ·@ConditionOnProperties:当存在指定属性配置时启用。
  • ·@ConditionOnResource:当存在指定资源时启用。
  • ·@ConditionOnWebApplication:当应用是一个Web应用时启用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值