profile用于指定bean所属的环境,只有当这个环境被激活时,对于的bean才会被装入容器中。profile最常见的应用是数据库环境的切换。可通过spring的 spring.profiles.active 和 spring.profiles.default 属性确定当前环境。
用两个简单的类来模拟两个不同的数据环境:
public class C3p0 {
String dataSource="C3p0数据源";
public C3p0(){
System.out.println(dataSource);
}
public void close(){}
}
public class Dbcp {
String dataSource="Dbcp数据源";
public Dbcp(){
System.out.println(dataSource);
}
public void close(){}
}
在配置文件中使用profile指定其所属的环境。
public class MyConfig {
@Bean(destroyMethod = "close")
@Profile("c3p0")
public C3p0 c3p0(){
return new C3p0();
}
@Bean(destroyMethod = "close")
@Profile("dbcp")
public Dbcp dbcp(){
return new Dbcp();
}
}
当然也在配置类级别上也可以使用profile,它告知了spring该配置类下所有的bean都属于这个环境。
测试:
public class testProfile {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
ConfigurableEnvironment environment = context.getEnvironment();
environment.setActiveProfiles("c3p0");
context.register(MyConfig.class);
context.refresh();
context.getBean("c3p0");
}
}
注:new AnnotationConfigApplicationContext();不用传入参数
public AnnotationConfigApplicationContext(Class... componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}
由源码可知传入配置类参数的构造函数会调用refresh()函数,而该函数在整个AnnotationConfigApplicationContext生命周期内只允许调用一次。这样会导致environment.setActiveProfiles(“c3p0”);无效。