导读:在开发环境与生产环境使用不同的参数,可以配置两套配置文件,通过@profile来激活需要的环境。
多环境集成开发中,不免会有很多配置,在容器中如果存在同一类型的多个组件,也可以使用@Profile
注解标识要获取的是哪一个bean
,这在不同的环境使用不同的变量的情景特别有用。例如,开发环境、测试环境、生产环境使用不同的数据源,在不改变代码的情况下,可以使用这个注解来切换要连接的数据库。
多环境集成开发中,不免会有很多配置,在容器中如果存在同一类型的多个组件,也可以使用@Profile
注解标识要获取的是哪一个
当一个或多个指定的配置文件处于活动状态时,表示组件有资格注册。
配置文件是一个命名的逻辑分组,可以通过ConfigurableEnvironment.setActiveProfiles
以编程方式激活,
也可以通过将spring.profiles.active
属性设置为 JVM 系统属性、环境变量或web.xml
的 Servlet
上下文参数以声明方式激活 web应用程序。
配置文件也可以通过@ActiveProfiles
注释在集成测试中以声明方式激活。
@Profile
注释可以通过以下任何一种方式使用:
@Component
注释的类的类型级注释,包括@Configuration
类@Bean
方法的方法级注解@Configuration
类标有@Profile
,所有的@Bean
方法和@Import
与该类相关联的注释将被忽略,除非一个或多个指定的简档是活动的。配置文件字符串可能包含简单的配置文件名称(例如"p1" )或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑,例如"p1 & p2" 。@Profile
注释,则无论哪个(如果有)配置文件处于活动状态,都会进行注册。@Bean
方法上使用@Profile
时,可能适用一种特殊情况:在重载相同Java 方法名称的@Bean
方法的情况下(类似于构造函数重载),需要在所有重载方法上一致地声明@Profile
条件. 如果条件不一致,则只有重载方法中第一个声明的条件才重要。@Profile
因此不能用于选择具有特定参数签名的重载方法而不是另一个方法;同一个 bean
的所有工厂方法之间的解析在创建时遵循 Spring
的构造函数解析算法。如果您想定义具有不同配置文件条件的替代 bean
,请使用指向相同bean name
不同 Java
方法名称。Spring
为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
开发环境develop
、测试环境test
、生产环境master
数据源:(/dev) (/test) (/master)
@Profile
:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
bean
,只有这个环境被激活的时候才能注册到容器中。默认是default
环境▐ 以下是在不同环境下不同的数据源组件的示例
package com.spring.config;
import java.beans.PropertyVetoException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* Profile:
* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
*
* 开发环境develop、测试环境test、生产环境master
* 数据源:(/dev) (/test) (/master)
*
* @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
*
* 1) 加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
* 2) 写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
*
*/
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
@Value("${db.user}")
private String user;
private String driverClass;
@Profile("default")
@Bean("test")
public DataSource testDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("dev")
@Bean("dev")
public DataSource devDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("master")
@Bean("master")
public DataSource masterDataSource(@Value("${db.password}")String password) throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setDriverClass(driverClass);
return dataSource;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
String driverClass = resolver.resolveStringValue("${db.driverClass}");
this.driverClass = driverClass;
}
}
▐ 以下是切换数据源示例
//创建匿名容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
//设置环境,其值为@Profile注解的属性值
applicationContext.getEnvironment().setActiveProfiles("test");
//注册容器类
applicationContext.register(ProfileBeanConfig.class);
//刷新容器
applicationContext.refresh();
在开发环境与生产环境使用不同的参数,可以配置两套配置文件,通过@profile
来激活需要的环境,但维护两套配置文件不如maven
中维护一套配置文件,在pom
中通过profile
来修改配置文件的参数来的实惠。
也有例外,比如我在开发中调用商城接口经常不能返回我需要的数据,每次都需要mock
数据,所以我写了一个mock
参数的借口调用类,在开发环境中就使用这个类,测试环境与生产环境则使用正常的借口调用类,这样就不用每次开发的时候去手动改一些代码。