์Šคํ”„๋ง YAML, @Profile

2023. 5. 11. 13:40ใ†์ธํ”„๋Ÿฐ/์Šคํ”„๋ง ๋ถ€ํŠธ - ํ•ต์‹ฌ ์›๋ฆฌ์™€ ํ™œ์šฉ

728x90

 

0๏ธโƒฃ YAML ์ด๋ž€? 

์Šคํ”„๋ง์€ ์„ค์ • ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ application.properties ๋ง๊ณ ๋„  appliction.yml YAML ํŒŒ์ผ ํ˜•์‹์„ ์ง€์›ํ•œ๋‹ค. 

์ด๋•Œ YAML ์ด๋ž€ YAML Ain't Markup Language ์˜ ์•ฝ์ž๋กœ ํ™•์žฅ์ž๋Š” yaml, yml๋กœ ์ฃผ๋กœ yml ์„ ์‚ฌ์šฉํ•œ๋‹ค. 

 

 

application.properties 

my.datasource.url=local.db.com
my.datasource.username=username
my.datasource.password=password
my.datasource.etc.max-connection=1
my.datasource.etc.timeout=3500ms
my.datasource.etc.options=CACHE,ADMIN

 

 

application.yml 

my:
  datasource:
    url: local.db.com
    username: local_user
    password: local_pw
    etc:
      max-connection: 1
      timeout: 60s
      options: LOCAL, CACHE

YAML์™€  application.properties๋ฅผ ๋น„๊ตํ•ด๋ณด๋ฉด application.properties๋Š” ํ‰ํ‰? ํ•˜๊ฒŒ ๋˜์–ด ์žˆ์–ด์„œ ๊ตฌ์กฐ ํŒŒ์•…์ด ์–ด๋ ต์ง€๋งŒ YAML ์€ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์ข‹๊ฒŒ ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. 

๊ทผ๋ฐ YAML ์€ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์ข‹๊ฒŒ ๊ณ„์ธต ๊ตฌ์กฐ ํ˜•ํƒœ๋ฅผ ๋„๋Š”๊ฑฐ์ง€ ์Šคํ”„๋ง์ด ์‹ค์ œ ์ฝ์„ ๋•Œ๋Š” ํ‰ํ‰ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์„œ ์ฝ๋Š”๋‹ค. 

 

YAML ์€ space(๊ณต๋ฐฑ)์œผ๋กœ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๊ณ  space๋Š” ๋ณดํ†ต 2์นธ์„ ์‚ฌ์šฉํ•˜๊ณ  ์ด๋•Œ ์ผ๊ด€์„ฑ ์žˆ์ง€ ์•Š๋‹ค๋ฉด ๊ตฌ์กฐ๊ฐ€ ๊นจ์งˆ ์ˆ˜๋„ ์žˆ๋‹ค. 

 

 

 

* ๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ application.properties์™€ application.yml์ด ๋‘๊ฐœ ๊ฐ™์ด ์žˆ๋‹ค๋ฉด application.properties๊ฐ€ ์šฐ์„ ๊ถŒ์„ ๊ฐ€์ง„๋‹ค๊ณ ๋Š” ํ•˜๋Š”๋ฐ ๋ณดํ†ต ์‹ค๋ฌด์—์„œ๋Š” properties๋ณด๋‹ค๋Š” yml ์ด ์ฝ๊ธฐ ํŽธํ•˜๊ธฐ ๋•Œ๋ฌธ์— yml์„ ์‚ฌ์šฉํ•œ๋‹ค. 

 

 

 

1๏ธโƒฃ ํ”„๋กœํ•„ ์„ค์ • 

YML ์—์„œ๋„ properties์™€ ๊ฐ™์ด ํ”„๋กœํ•„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. 

my:
  datasource:
    url: local.db.com
    username: local_user
    password: local_pw
    etc:
      max-connection: 1
      timeout: 60s
      options: LOCAL, CACHE

---
spring:
  config:
    activate:
      on-profile: dev

my:
  datasource:
    url: dev.db.com
    username: dev_user
    password: dev_pw
    etc:
      max-connection: 10
      timeout: 60s
      options: DEV, CACHE

---
spring:
  config:
    activate:
      on-profile: prod

my:
  datasource:
    url: prod.db.com
    username: prod_user
    password: prod_pw
    etc:
      max-connection: 50
      timeout: 10s
      options: PROD, CACHE

yml ์—์„œ๋Š” ---- ์„ ์‚ฌ์šฉํ•ด ๋…ผ๋ฆฌ ํŒŒ์ผ์„ ๊ตฌ๋ถ„ํ•˜๊ณ , 

spring.config.active.on-prifle ์„ ์‚ฌ์šฉํ•ด์„œ ํ”„๋กœํ•„์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

2๏ธโƒฃ @Profile 

application.yml ์— ํ”„๋กœํ•„์„ ์„ค์ •ํ•ด์„œ ํ”„๋กœํ•„์— ๋”ฐ๋ผ ๊ฐ ํ™˜๊ฒฝ์— ๋งž๋Š” ์„ค์ •๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋Š”๋ฐ 

๋งŒ์•ฝ ์„ค์ •๊ฐ’ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ ํ™˜๊ฒฝ๋งˆ๋‹ค ์„œ๋กœ ๋‹ค๋ฅธ ๋นˆ์„ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค๋ฉด ? ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ ? 

์˜ˆ๋กœ ๊ฒฐ์ œ ๊ธฐ๋Šฅ์ธ๋ฐ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์‹ค์ œ ๊ฒฐ์ œ๊ฐ€ ๋˜์•ผ ํ•˜๋Š”๊ฒŒ ๋งž์ง€๋งŒ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ํ…Œ์ŠคํŠธํ•˜๋Š”๋ฐ ์‹ค์ œ ๊ฒฐ์ œ๊ฐ€ ๋˜๋ฉด ์•ˆ๋œ๋‹ค. 

์ด๋Ÿด ๋•Œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์‹ค์ œ ๊ฒฐ์ œ๊ฐ€ ๋˜๋Š” ๋นˆ์„ ๋“ฑ๋กํ•˜๊ณ , ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ€์งœ ๊ฒฐ์ œ ๊ธฐ๋Šฅ์˜ ๋นˆ์„ ๋“ฑ๋กํ•˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค. 

 

 

PayClient

public interface PayClient
{
   void pay(int money);
}

 

LocalPayClient

@Slf4j
public class LocalPayClient implements PayClient
{
   @Override
   public void pay(int money)
   {
      log.info("๋กœ์ปฌ ๊ฒฐ์ œ money = {} ", money);
   }
}

 

 

ProdPayClient

@Slf4j
public class ProdPayClient implements PayClient
{
   
   @Override
   public void pay(int money)
   {
      log.info("์šด์˜ ๊ฒฐ์ œ money = {} ", money);
   }
}

 

 

OrderService

@Service
@RequiredArgsConstructor
public class OrderService
{
   private final PayClient payClient;
   
   public void order(int money)
   {
      payClient.pay(money);
   }
}

OrderService๋Š” PayClient๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์œผ๋กœ ์ƒํ™ฉ์— ๋”ฐ๋ผ LocalPayClient ๋˜๋Š” ProdPayClient๋ฅผ ์ฃผ์ž… ๋ฐ›๋„๋ก ํ•œ๋‹ค. 

 

 

PayConfig

@Slf4j
@Configuration
public class PayConfig
{
   @Bean
   @Profile("default")
   public LocalPayClient localPayClient()
   {
      log.info("LocalPayClient ๋นˆ ๋“ฑ๋ก");
      return new LocalPayClient();
   }
   
   @Bean
   @Profile("prod")
   public ProdPayClient prodPayClient()
   {
      log.info("ProdPayClient ๋นˆ ๋“ฑ๋ก");
      return new ProdPayClient();
   }
}

@Profile ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ํ•ด๋‹นํ•˜๋Š” ํ”„๋กœํ•„์ด ํ™œ์„ฑํ™”๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋นˆ์„ ๋“ฑ๋กํ•˜๋„๋ก ํ•œ๋‹ค. 

default ํ”„๋กœํ•„์ด ํ™œ์„ฑํ™” ๋˜๋ฉด LocalPayClient ๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ , 

prod ํ”„๋กœํ•„์ด ํ™œ์„ฑํ™” ๋˜๋ฉด ProdPayClient ์„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค. 

 

 

OrderRunner 

@Component
@RequiredArgsConstructor
public class OrderRunner implements ApplicationRunner
{
   private final OrderService orderService;
   
   @Override
   public void run(ApplicationArguments args) throws Exception
   {
      orderService.order(1000);
   }
}

ApplicationRunner ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํ”„๋ง์€ ์ด์ œ ๋นˆ ์ดˆ๊ธฐํ™”๋ฅผ ๋๋‚ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋Š” ์‹œ์ ์— run ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

 

@Profile prod ์ธ ๊ฒฝ์šฐ 

prod๋กœ ํ”„๋กœํ•„ ์ ์šฉํ–ˆ์„ ๋•Œ๋Š” ProdPayClient ๊ฐ€ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

๐Ÿ’Œ @Profile ์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ํ•ด๋‹น ๋นˆ์„ ๋“ฑ๋กํ• ์ง€ ๋ง์ง€ ์„ ํƒํ•œ๋‹ค. 

@Profile ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ํ™˜๊ฒฝ ๋ณ„๋กœ ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ๋ถ„๋ฆฌ๋ฅผ ํฌํ•จํ•ด์„œ ์Šคํ”„๋ง ๋นˆ๋„ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

728x90