spring的profiles为多环境配置提供了最佳事件,如果一个系统需要qa测试环境与上线环境,两个环境的数据源不一样,传统的数据源配置是这样的
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
这种情况下你要考虑怎么在两个不同的环境下切换数据源通常依赖于系统环境变量和包含${placeholder}的XML 语句的组合,这些placeholder根据环境变量的值解析为正确的配置。Bean definition profiles 为这个问题提供了一个解决方案。
使用@Profile注解重写dataSource bean如下
@Configuration
@Profile("development")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
@Configuration
@Profile("production")
public class JndiDataConfig {
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
@Profile注解可以用于创建自定义注解的元数据说明。代码如下
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("production")
public @interface Production {
}
这个就可以使用@production代替@Profile。
XML bean definition profiles
怎样激活一个配置环境呢?
最直接的办法就是通过Environment
的API来编程指定
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("development");
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
ctx.refresh();
也可以通过制定变量spring.profiles.active的值来声明
使用默认的配置环境
@Configuration
@Profile("default")
public class DefaultDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.build();
}
}
@PropertySource 读取资源配置文件,用法如下
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
使用占位符读取配置文件
@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
my.placeholder可以通过system propertie或者environment variables来注册。如果不指定就会使用默认的default/path
对于StandardServletEnvironment,寻找property的优先级如下
DispatcherServlet
context)参考:https://docs.spring.io/spring/docs/4.3.22.RELEASE/spring-framework-reference/htmlsingle/#beans-definition-profiles