Spring - Profile

标签:翻译 Spring
原文地址: https://www.baeldung.com/spring-profiles

更多Spring实战内容,请参考Spring - 实战指南

1. 概述

这篇文章将阐述怎么在Spring中使用Profile

从Spring 3.1开始,我们能够将bean映射到不同的profile上,如dev, test, prod等。

我们也能够根据环境(environment)来激活不同的profile,从而加载我们需要的bean。

2. 在Bean上使用@Profile

我们先从简单的例子开始,看看怎么把bean绑定到不同的profile上。

使用@Profile注解,我们可以将bean绑定到指定的profile上。这个注解支持绑定一个或多个profile。

试想这样一个场景:我们有一个bean,只在开发环境需要,线上环境不需要。那么我们可以通过注解将这个bean绑定到dev profile上。这样,这个bean只会存在于开发环境,而在其他环境中不会被加载。如下所示:

@Component
@Profile("dev")
public class DevDatasourceConfig

上面的写法是指绑定bean到dev profile。如果想绑定bean到除dev以外的profile呢。可以使用NOT操作符。如下所示:

@Component
@Profile("!dev")
public class DevDatasourceConfig

译者注:
@Profile的声明如下:

public @interface Profile {
   String[] value();
}

value是个数组,支持多个值。绑定多个profile,如下所示:

@Profile(value = {"dev", "test"})

3. 在XML中声明Profile

除了使用@Profile注解,还可以在XML中绑定profile。

标签有个profiles属性。多个profile之间使用逗号分隔:

profile还是profiles???


    

4. 设置profile

上面只是将bean和profile进行了绑定,下一步需要设置和激活profile,才能使不同的bean被注册到容器中。方法有很多种,下面是一些例子:

4.1 使用WebApplicationInitializer interface

这是一种编程的方式(与之对应是配置方式)

在web应用中,WebApplicationInitializer可以被用来配置ServletContext

译者注:
WebApplicationInitializer在spring-web中

方法如下:

@Configuration
public class MyWebApplicationInitializer 
  implements WebApplicationInitializer {
 
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
  
        servletContext.setInitParameter(
          "spring.profiles.active", "dev");
    }
}

译者注:
这种方式,直接把要绑定的profile硬编码到代码中,是非常不优雅,也不方便的。

4.2 使用ConfigurableEnvironment

你也可以直接在环境中设置profile:

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

译者注:
问题同4.1

4.3 在web.xml中配置


    contextConfigLocation
    /WEB-INF/app-config.xml


    spring.profiles.active
    dev

译者注:
问题同4.1,4.2。 本人不赞成任何硬编码的方式

4.4 通过JVM参数设置

profile的名字还可以通过JVM参数的方式设置。在启动的时候,添加类似如下参数:

-Dspring.profiles.active=dev

译者注:
java -jar xxx.jar -Dspring.profiles.active=dev

4.5 通过环境变量设置

通过设置环境变量,也是可以的:

export spring_profiles_active=dev

4.6 Maven Profile

Spring profile也可以结合maven profile使用,通过设置spring.profiles.active属性:


    
        dev
        
            true
        
        
            dev
        
    
    
        prod
        
            prod
        
    

同时,还需要在application.properties(如果使用spring boot的话)中添加如下设置:

[email protected]@

另外,还需要再pom.xml文件中添加如下配置:


    
        
            src/main/resources
            true
        
    
    ...

译者注:
pom.xml中添加的配置,意思是开启占位符替换。可参考:Maven Filtering

结合使用maven profile后,就可以在打包的时候激活某个profile:

mvn clean package -Pprod

译者注:
个人认为,结合maven profile的这种办法,灵活度最高,也最方便,推荐。

4.7 Test中使用@ActiveProfiles

在test时,如何指定profile呢?也很简单,通过@ActiveProfiles注解就可以了。

@ActiveProfiles("dev")

5. 默认profile

如果不指定任何profile,那么这个bean就属于default profile

当没有任何profile被激活时,spring也支持设置默认profile。就是通过spring.profiles.default参数。

6. 获取被激活的profile

一旦profile被激活,我们就可以通过Environment,在运行时获取这些profile的信息:

public class ProfileManager {
    @Autowired
    Environment environment;
 
    public void getActiveProfiles() {
        for (final String profileName : environment.getActiveProfiles()) {
            System.out.println("Currently active profile - " + profileName);
        }   
    }
}

7. 使用Profile的例子

理论总是抽象的,下面我们通过一些例子来深入理解。

试想这样一个场景:我们要分别针对开发环境和线上环境,对datasource进行设置。我们先创建一个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。那么我们通过设置不同的profile,就会分别注入DevDatasourceConfig bean和ProductionDatasourceConfig bean。

public class SpringProfilesTest {
    @Autowired
    DatasourceConfig datasourceConfig;
 
    public void setupDatasource() {
        datasourceConfig.setup();
    }
}

dev profile被激活的时候,会有如下输出:

Setting up datasource for DEV environment.

8. 在Spring Boot中使用Profile

Spring Boot除了支持所有的profile配置,还有提供一些额外功能。

spring.profiles.active的初始化可以在配置文件中设定:

spring.profiles.active=dev

当然也可以在程序中设定:

SpringApplication.setAdditionalProfiles("dev");

还可以在pom.xml文件中的spring-boot-maven-plugin中配置:


    
        org.springframework.boot
        spring-boot-maven-plugin
        
            
                dev
            
        
    
    ...

用maven启动,可执行命令:

mvn spring-boot:run

但是Spring Boot带来的最重要的特性是profile-specific profiles文件,这些文件的命名方式需要遵循applications-{profile}.properties的格式。

举个例子:我们可以在开发环境和线上环境使用不同的数据库。如开发环境使用h2,线上环境使用mysql。那么,我们分别需要创建如下两个文件:

application-production.properties

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

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

如果激活的profile是dev,则application-dev.properties配置文件会被自动加载。如果激活的profile是production,则application-production.properties 配置文件会被加载。

通过这种方式,我们就很容易地针对不同环境,配置不同的配置文件。

你可能感兴趣的:(Spring - Profile)