Spring注解驱动开发——Profile环境切换

版权声明:本文为博主原创文章,未经博主允许不得转载。 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}");
	}
}
 

猜你喜欢

转载自blog.csdn.net/rubulai/article/details/80544528
今日推荐