1.概述
在本文中,我们将介绍Spring中的Profiles。
Spring的配置文件功能允许我们将bean映射到不同的配置文件。
例如,dev,test,prod。
然后,我们可以在不同的环境中激活不同的配置文件,来引导使用需要的bean。
2. 在Bean上使用@Profile
让我们从最简单开始,看看我们如何使bean属于特定的配置文件。
我们可以使用*@Profile*注释将bean映射到该特定的配置文件; 注释只是采用一个(或多个)配置文件的名称。
一个基本场景 :
我们有一个bean,它应该只在开发期间需要,而不应该在生产环境中部署。
我们可以使用profile注释标记该bean ,并且它只会在开发期间出现在容器中。
在生产环境中,dev将不会处于活动状态:
@Component
@Profile("dev")
public class DevDatasourceConfig
Profile的名称也可以使用NOT运算符作为前缀,例如“ !dev ”以将其从配置文件中排除。
在下面的示例中,仅当“ dev ”Profile未激活时才激活组件:
@Component
@Profile("!dev")
public class DevDatasourceConfig
3.以XML格式声明配置文件
配置文件也可以用XML配置。
*
<beans profile="dev">
<bean id="devDatasourceConfig"
class="org.baeldung.profiles.DevDatasourceConfig" />
</beans>
4.设置使用的Profile
下面我们看一下是激活和设置Profile,以便在容器中注册相应的bean。
这可以通过多种方式完成。
4.1 通过WebApplicationInitializer接口
在Web应用程序中,WebApplicationInitializer可用于以编程方式配置ServletContext。
以编程方式设置我们的设置要使用的配置文件:
@Configuration
public class MyWebApplicationInitializer
implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter(
"spring.profiles.active", "dev");
}
}
4.2 通过ConfigurableEnvironment
还可以直接在环境中设置要使用的配置文件:
@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");
4.3 web.xml中的 Context参数
同样,也可以使用context参数在Web应用程序的web.xml中激活配置文件:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
4.4 JVM系统参数
配置文件名称也可以通过JVM系统参数传递。
作为参数传递的配置文件名称将在应用程序启动期间激活:
-Dspring.profiles.active=dev
4.5 环境变量
在Unix环境中,还可以通过环境变量激活配置文件:
4.6 Maven Profile
我们也可以通过Maven配置文件激活Spring配置文件,通过指定spring.profiles.active 配置属性。
在Maven的Profile中,我们都可以设置spring.profiles.active属性:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
最终会使用spring.profiles.active值替换application.properties中的占位符
[email protected]@
不过,我们需要在pom.xml中启用资源过滤:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
然后我们在Maven中就可以使用*-P*参数来切换配置文件:
mvn clean package -Pprod
4.7 在测试中使用@ActiveProfile
在测试中可以非常轻松地指定使用哪些配置文件。 -
使用*@ActiveProfile*注释启用特定配置文件:
@ActiveProfiles("dev")
总而言之,我们有多种激活配置文件的方法。他们的优先级如下:
- web.xml中的 Context参数
- WebApplicationInitializer
- JVM系统参数
- 环境变量
- Maven Profile
5.默认的配置文件
任何未指定配置文件的bean都属于“ default ”配置文件。
Spring还提供了一种在没有其他配置文件处于激活状态时设置默认配置文件的方法,使用“ spring.profiles.default ”属性。
6.获取激活的配置文件
Spring的配置文件可以使用*@Profile*注释的行为以启用/禁用bean。但是,我们可能还希望以编程方式访问激活配置文件。
我们有两种方法可以访问到Environment或spring.active.profile。
6.1 使用Environment
我们可以通过注入Environment, 从Environment对象访问激活的配置文件:
public class ProfileManager {
@Autowired
private Environment environment;
public void getActiveProfiles() {
for (String profileName : environment.getActiveProfiles()) {
System.out.println("Currently active profile - " + profileName);
}
}
}
6.2 使用spring.active.profile
我们还可以通过注入属性spring.profiles.active来访问配置文件 :
@Value("${spring.profiles.active}")
private String activeProfile;
在这里,我们的activeProfile 变量将包含当前激活的配置文件的名称,如果有多个,它将是通过以逗号分隔名称。
但是,我们应该考虑如果根本没有激活的配置文件会发生什么。
使用上面的代码,缺少激活配置文件会阻止创建应用程序上下文。最后导致*IllegalArgumentException,*因为缺少占位符注入变量。
为了避免这种情况,我们可以定义一个默认值:
@Value("${spring.profiles.active:}")
private String activeProfile;
7. 使用配置文件的示例
现在让我们来看看一个真实的例子。
假设我们必须维护开发和生产环境的数据源配置。让我们创建一个需要由两个数据源实现实现的公共接口DatasourceConfig:
public interface DatasourceConfig {
public void setup();
}
开发环境的配置:
@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
@Override
public void setup() {
System.out.println("Setting up datasource for DEV environment. ");
}
}
生产环境的配置:
@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
@Override
public void setup() {
System.out.println("Setting up datasource for PRODUCTION environment. ");
}
}
现在让我们创建一个测试并注入我们的DatasourceConfig接口;
根据配置文件,Spring将注入DevDatasourceConfig或ProductionDatasourceConfig 的bean:
public class SpringProfilesWithMavenPropertiesIntegrationTest {
@Autowired
DatasourceConfig datasourceConfig;
public void setupDatasource() {
datasourceConfig.setup();
}
}
当“ dev ”配置文件处于激活状态时,spring会注入DevDatasourceConfig对象,并且在调用*setup()*方法时,输出如下:
Setting up datasource for DEV environment.
8. Spring Boot中的配置文件
Spring Boot支持到目前为止概述的所有配置文件配置,还有一些附加功能。
比如我们之前介绍的spring.profiles.active,在spring boot也可以用来设置文件
spring.profiles.active=dev
要以编程方式设置配置文件,我们还可以使用SpringApplication类:
SpringApplication.setAdditionalProfiles("dev");
要在Spring Boot中使用Maven设置配置文件的话,我们可以在pom.xml中的spring-boot-maven-plugin下指定配置文件名称
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>
<profile>dev</profile>
</profiles>
</configuration>
</plugin>
...
</plugins>
并执行Spring Boot特定的Maven命令:
mvn spring-boot:run
但是Spring Boot带来的最重要的与配置文件相关的功能是特定于配置文件的属性文件。这些必须以application- {profile} .properties格式命名。
比如,我们可以使用名为application-dev.properties和application-production.properties的两个文件为dev和prod配置文件配置不同的数据源:
在application-production.properties文件中,我们可以设置MySql数据源:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root
然后,我们可以在application-dev.properties文件中为dev配置文件配置相同的属性,以使用内存中的H2数据库:
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
通过这种方式,我们可以轻松地为不同的环境提供不同的配置。
9.结论
在本文中,我们讨论了如何在bean上定义配置文件以及如何在我们的应用程序中启用正确的配置文件。
最后,我们通过一个简单的例子验证了我们对配置文件的理解。
最后的最后,往常一样,代码可以在Github上找到。