版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rubulai/article/details/80544528
Profile:Spring提供的可以根据当前环境(开发、测试、生产),动态的激活和切换一系列的组件的功能,可以使用@Profile注解实现,比如数据源根据环境的切换。@Profile注解用于指定组件在哪个环境下会注册到IOC容器中,若不加该注解则在所有环境下都会注册到容器中:
@PropertySource("classpath:/config.properties")
@Configuration
public class MyProfileConfig implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
private String driverClass;
@Bean
public DataSource devDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
return dataSource;
}
@Bean
public DataSource testDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
public DataSource proDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/pro");
return dataSource;
}
//可以在此处给driverClass赋值说明此方法的调用时机在bean创建之前
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.driverClass = resolver.resolveStringValue("${db.driverClass}");
}
}
没有加@Profile注解,则容器中会有三个数据源对象,这里使用了三种不同的方式为属性赋值(@Value或者SpringValueResolver都可以)
@PropertySource("classpath:/config.properties")
@Configuration
public class MyProfileConfig implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
private String driverClass;
@Bean
@Profile("dev")
public DataSource devDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
return dataSource;
}
@Bean
@Profile("test")
public DataSource testDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
@Profile("pro")
public DataSource proDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/pro");
return dataSource;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.driverClass = resolver.resolveStringValue("${db.driverClass}");
}
}
加了环境标识(@Profile)的bean,只有在这个环境被激活时该bean才会被注册到IOC容器中,容器的默认环境是default,即在不设置容器的环境的情况下所有的@Profile("default")和不加@Profile注解的bean都会注册到容器中,那么怎么改变容器的环境呢?
1、使用命令行参数在Run Configuration的VM arguments中设置:-Dspring.profiles.active的值
-Dspring.profiles.active=test
此时则容器中只有testDataSource
2、使用代码的方式为容器设置启用环境:
public void test1() throws Exception {
// 1、创建容器对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 2、设置容器的环境:此操作要在注册配置bean之前,可以设置多个环境
context.getEnvironment().setActiveProfiles("dev", "test");
// 3、注册配置bean
context.register(MyProfileConfig.class);
// 4、刷新容器
context.refresh();
context.close();
}
注意此时在创建IOC容器的时候必须使用无参构造器创建,因为有参构造器在创建对象时就会注册配置bean并刷新容器,此时即使再设置其容器环境也已经迟了,因为bean已经创建了,AnnotationConfigApplicationContext的有参构造:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
属性文件:
db.user=root
db.password=123456
db.driverClass=com.mysql.jdbc.driver
也可以将@Profile注解标注在配置类上,此时该配置类只有在与IOC容器环境一致时才会被注册到IOC容器中
@Profile({"test","dev"})
@Configuration
@PropertySource("classpath:/config.properties")
public class MyProfileConfig implements EmbeddedValueResolverAware {
@Value("${db.user}")
private String user;
private String driverClass;
@Bean
@Profile("dev")
public DataSource devDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
return dataSource;
}
@Bean
@Profile("test")
public DataSource testDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
@Profile("pro")
public DataSource proDataSource(@Value("${db.password}") String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/pro");
return dataSource;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.driverClass = resolver.resolveStringValue("${db.driverClass}");
}
}