[Spring Boot] Spring Profiles

Spring Boot

Language :

In general, the server development environment consists of Local, Dev, Staging, and Product.

Management of multiple environments is essential because settings such as database connections and tokens vary depending on each environment.

In Spring Boot, multiple environments can be managed through Profiles.

Profile Settings File

It is a file that collects settings according to the development environment.

It is located in the resources folder and managed as an application.properties or application.yml file.

Project
└ src
   └ main
      └ resources
         └ application.yml

Settings File Name Rule

application-{profile_name}.properties
application-{profile_name}.yml

Setting Method 1. Creating a setting file by profile

application.yml

  • Sets variables that are common to all profiles.
  • For spring.profiles.active, specify the profile_name to activate. In the example, the system environment variables were read and set.
spring:
    profiles:
        active: ${BACKEND_MODE}
server:
    port: 8081
  • Example) Set the system environment variable in the .env file (Docker)
BACKEND_MODE=dev

application-dev.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dico
    driver-class-name: com.mysql.jdbc.Driver
    username: test_user
    password: test_pwd
api:
  base-url: http://localhost/api/v1/auth
  token: 9OySm75tZHjg3jUTgaE

application-stage.yml

spring:
  datasource:
    url: jdbc:mysql://stage-mysql:3306/dico
    driver-class-name: com.mysql.jdbc.Driver
    username: stage_user
    password: stage_pwd
api:
  base-url: https://example.com/api/v1/auth
  token: 80Xycvd9DlrNC7xM5Rz

application-prod.yml

spring:
  datasource:
    url: jdbc:mysql://prod-mysql:3306/dico
    driver-class-name: com.mysql.jdbc.Driver
    username: prod_user
    password: prod_pwd
api:
  base-url: https://example.com/api/v1/auth
  token: Qr8yYKNI0wASP7wjUCz

In this case, the stage and prod files can be set up in .gitignore to prevent them from being uploaded to GitHub, and can be managed through CI/CD to increase security.

Setting Method 2. Manage each profile with one setup file

application.yml

  • Create profiles separated by '---' in one file.
spring:
  profiles:
    active: ${BACKEND_MODE}
---

spring:
  config:
    activate:
      on-profile: dev
# ... dev settings
---

spring:
  config:
    activate:
      on-profile: stage
# ... stage settings
---

spring:
  config:
    activate:
      on-profile: prod
# ... prod settings

Setting Method 3. Use only one profile

application.yml

  • Different setting values for each environment are set as system environment variables.
  • It has the disadvantage of having to generate all OS system environment variables.
server:
    port: 8081
spring:
  datasource:
    url: ${MUSQL_URL}
    driver-class-name: com.mysql.jdbc.Driver
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}
api:
  base-url: ${API_BASE_URL}
  token: ${API_TOKEN}

Binding Method (Bean Property Annotation)

Using @Profile

  • If the defined profile is activated, the corresponding component is registered in the bean.
  • Dynamic binding, which operates at runtime (a step in which a program is executed and operated).
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Service

@Service
@Profile("dev") // When profile dev is activated, it is empty registered.
class DevMailerServiceImpl : MailerService { }

@Service
@Profile("stage") // When profile stage is activated, it is empty registered.
class StageMailerServiceImpl : MailerService { }

@Service
@Profile("prod") // When profile prod is activated, it is empty registered.
class ProdMailerServiceImpl : MailerService { }
@Service
class HelpService(
    private val mailerService: MailerService  // The MailerService implementation varies depending on the profile enabled.
) { }

Using @Value

  • Injects the value set in the activated profile into the variable.
  • Static binding, which operates at the time of compilation (step of converting source code into an executable form).
  • In the example, 'Qr8yKNI0wASP7wjUCz' is injected into the variable token because dev is enabled in the profile.
@Component
class ApiProvider(
    @Value("\${api.base-url}") private val baseUrl: String,
    @Value("\${api.token}") private val token: String
) {

Reference

https://www.springcloud.io/post/2022-09/spring-boot-profiles

민갤

Back-End Developer

백엔드 개발자입니다.