Spring Boot Profiles的完整指南

784 阅读5分钟

1.弹簧配置文件

1.1.什么是配置文件?

一般来说,配置文件是对Spring应用程序可以运行的不同运行环境的隔离。例如,一个应用程序可以在本地、开发或测试环境以及生产环境中运行。在上述所有的部署环境中复制相同的硬件和软件设置并不容易。因此,我们的期望是以这样一种方式配置应用程序,使其在所有这些环境中都能正常运行。

有趣的是,一个配置文件不仅限于部署环境。它可以是任何类型的隔离。例如,一个应用程序可以在一个配置文件中连接到MySQL数据库,而它将在另一个配置文件中连接到H2数据库。因此,在这里我们有数据库配置的特定配置文件。同样,配置文件也可以在任何基础上进行隔离。

因此,简单地说,spring profiles的目的是在启动时在不同的环境中激活不同的bean。在引擎盖下,一个配置文件只能控制两件事。

  • 哪些Bean被加载到应用程序上下文中
  • 应用哪些应用程序属性

1.2.什么是默认配置文件?

在进一步深入了解这个概念之前,关键是要理解,如果我们没有明确指定任何配置文件,那么default 配置文件会自动激活。

当使用默认配置文件时,所有不属于任何特定配置文件的bean都将被初始化。所有特定配置文件的Bean将被跳过初始化。

这相当于在所有不属于任何特定配置文件的bean上使用@Profile("default") 注释。

默认配置文件的名称可以使用spring.profiles.default属性进行调整,如下面的例子中所示。这将把默认配置文件的名称从default改为none

spring.profiles.default=none

2.@Profile 注释

2.1.使用@Profile

@Profile被用在以下注解的类中。

例如,如果我们有三个配置文件localdevprod,那么我们可以使用以下三个类来定义配置文件的特定bean。

@Profile("local")
@Configuration
public class LocalProfileConfiguration {

   @Bean
   public DataSource h2DataSource() {/*...*/}
}
@Profile("dev")
@Configuration
public class DevelopmentProfileConfiguration {

   @Bean
   public DataSource mySqlDataSource() {/*...*/}
}
@Profile("prod")
@Configuration
public class ProductionProfileConfiguration {

   @Bean
   public DataSource oracleDataSource() {/*...*/}
}

同样地,我们也可以使用*@Profile*注解与定型注解。

注意,配置文件的名字也可以用NOT操作符作为前缀。!prod名称在所有非生产环境中配置豆子。

@Profile("!prod")
@Configuration
public class NonProductionProfileConfiguration {

   @Bean
   public DataSource h2DataSource() {/*...*/}
}

2.2.不是最佳实践

尽管*@Profile*是一个非常有用和简单的概念,但它仍然有一个明显的缺点。它将源代码中的特定配置分散到多个地方。而且,它使我们很难随着时间的推移跟踪配置文件的具体配置。

另一个问题是激活多个配置文件会导致重复的Bean和运行时异常。例如,假设我们在MemoryDataSourcelocal两个不同的配置文件中有H2 DataSource Bean定义。

@Profile("inMemoryDataSource")
@Configuration
public class DevelopmentProfileConfiguration {

   @Bean
   public DataSource datasource() {/*...*/}
}
@Profile("local")
@Configuration
public class ProductionProfileConfiguration {

   @Bean
   public DataSource datasource() {/*...*/}
}

如果我们决定在运行时激活inMemoryDataSourcelocal这两个配置文件,那么就会有两个相同类型的bean,这将导致运行时错误。

因此,如果我们决定使用@Profile 注释,拥有一个适当的隔离配置和Bean是困难的,但却是最重要的。最好是使用application.properties文件作为控制配置文件特定配置和属性的中心位置。

3.配置文件的特定属性

3.1.配置文件的特定属性文件

Spring Boot允许将不同环境的配置参数分组到不同的application.properties配置文件中。Spring Boot将根据激活的配置文件自动选择正确的配置文件,并从该文件中加载配置属性。

属性文件必须以application-{profile}.properties 的格式命名。例如。

  • application.properties- 包含适用于所有环境的属性
  • application-local.properties- 在本地配置文件被激活时配置应用程序
  • application-dev.properties- 当devprofile被激活时配置应用程序
  • application-prod.properties - 当prod配置文件被激活时配置应用程序。

例如,如果我们在不同的环境中有不同的数据库,那么我们可以像下面的例子一样创建单独的属性文件。

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=
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=password

3.2.application.properties中的多个配置文件

也可以只在 application.properties文件中指定所有配置文件的具体配置,使用spring.config.activate.on-profile 属性作为分隔符来表示配置文件。

application.name=My Application

#--- local profile ---#
spring.config.activate.on-profile=local
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=

#--- dev profile ---#
spring.config.activate.on-profile=dev
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=password

请注意,我们不能在配置文件特定的文件中使用spring.profiles.active以及与spring.config.activated.on-profile属性一起使用。下面是一个无效的配置。

# Valid usecase
spring.profiles.active=prod

# Invalid usecase
spring.config.activate.on-profile=prod
spring.profiles.active=dev

4.配置文件组

从Spring boot 2.4开始,我们也可以定义配置文件组。配置文件组允许将类似的配置文件分组。

例如,如果我们有不同的配置文件用于生产配置,如prodJmsprodDatabaseprodJndi等,并且我们希望在生产中部署应用程序时激活所有这些配置文件。要做到这一点,我们可以将所有这些配置文件分组在一个配置文件名称下。

spring.profiles.group.prod=prodJms,prodDatabase,prodJndi

有了上述配置文件组的定义,激活prod配置文件将同时激活prodJmsprodDatabaseprodJndi

5.激活一个配置文件

spring.profiles.active是一个标准属性,Spring Boot会自动拾取它来激活一个profile。将配置文件的名称传递给这个属性值来激活该配置文件。

如果我们想激活多个配置文件,那么我们可以传递这些配置文件的逗号分隔的名称。

我们可以在很多地方设置它,例如,在application.properties文件中。

spring.profiles.active=dev

作为JVM的启动参数。

$ java -jar app.jar -Dspring.profiles.active=dev

作为环境变量。

export spring_profiles_active=dev

在配置WebApplicationInitializer时。

@Configuration
public class CustomWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        servletContext.setInitParameter("spring.profiles.active", "dev");
    }
}

6.结论

在这个Spring boot教程中,我们了解了有助于隔离不同部署环境的配置和属性的profile,但不限于此。

我们学习了如何创建特定于配置文件的配置和bean。我们学会了在运行时和配置文件组中激活一个特定的配置文件。

学习愉快!!

源代码在Github上