我们在编程的时候,难免需要不断的在开发和生产环境进行切换,这过程我们的数据库连接和缓存的配置等都很可能不一样,例如生产我们用的是MenCache做缓存的,开发环境是用的是Redis,这需要我么来切换,手动切换是很忌讳的,因为手工总是不靠谱的,难免会忘记切换了,我们需要的是自动化的方式,对此我们可以用两种方式来解决
- @Profile
- @Conditonal
例子如下
@profile登场
看一下关于profile的简单演示
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public BaseCache redisCache() {
return new RedisCache();
}
@Bean
@Profile("product")
public BaseCache menCache() {
return new MenCache();
}
}
这两个bean不会被注册,除非我们激活他们
激活的方式很多,下面提供一种常见的
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("dev");
ctx.register(DataSourceConfig.class);
ctx.refresh();
这样我们就可以用所有profile是dev
的bean了。
另外,在测试环境,spring提供了一个ActiveProfiles
, 具体的使用如下
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DataSourceConfig.class)
@ActiveProfiles("dev")
public class ConditionalTest {
@Test
public void testProfiles() {
BaseCache baseCache = context.getBean(BaseCache.class);
if (baseCache != null) {
System.out.println(" cache name =" + baseCache.getCacheName());
}
}
}
当然,这个还是不够自动化,仍然需要我们去手动的控制这个我们到底选中的是哪一个bean;
为此,我们推荐一个新的东东,叫@Conditoanl
@Conditonal登场
啥也不说,先show you the code!
@Configuration
public class DataSourceConfig {
@Bean
@Conditional(ProductExistsCondition.class)
public BaseCache redisCache() {
return new RedisCache();
}
@Bean
@Conditional(DevExistsCondition.class)
public BaseCache menCache() {
return new MenCache();
}
}
这些bean都被赋予了一个条件类,当这个条件类返回真的时候,这个bean
就会被激活;
来看下ProductExistsCondition
是怎样的
public class ProductExistsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
System.out.println("matching");
String profile = System.getProperty("profile").toLowerCase();
System.out.println(" profile name="+profile);
return !profile.startsWith("product");
}
}
再来看下这个开发环境下的条件类
public class DevExistsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
System.out.println("matching");
String profile = System.getProperty("profile").toLowerCase();
System.out.println(" profile name="+profile);
return !profile.startsWith("dev");
}
}
我们的条件类事实现了spring提供的Conditon接口的,然后供spirng调用,这个接口返回为真,则激活该bean,为false则不激活。另外我们设置系统的属性里面加多一个叫“profile”的环境变量,这样我们就可以全自动的切换到不同的环境去,只要我们在系统的环境变量里面加多了一个profile的属性。并将他的值设置成了dev,那么这台电脑就是开发环境下的。