chap 5 3 - JAVA-JIKIMI/SPRING-IN-ACTION-5 GitHub Wiki

ꡬ성 속성 μ‚¬μš©ν•˜κΈ° :: ν”„λ‘œνŒŒμΌ μ‚¬μš©ν•΄μ„œ κ΅¬μ„±ν•˜κΈ°

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ„œλ‘œ λ‹€λ₯Έ λŸ°νƒ€μž„ ν™˜κ²½μ— 배포, μ„€μΉ˜λ  λ•ŒλŠ” λŒ€κ°œ ꡬ성 λͺ…μ„Έκ°€ 달라진닀.

μ΄λ•Œ 각 ν™˜κ²½μ˜ 속성듀을 application.yml에도 μ„€μ •ν•  수 있고

λ˜ν•œ 운영체제의 ν™˜κ²½ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•΄μ„œ μ„€μ •ν•  μˆ˜λ„ μžˆλ‹€.

ν•˜μ§€λ§Œ ν•˜λ‚˜ μ΄μƒμ˜ ꡬ성 속성을 ν™˜κ²½ λ³€μˆ˜λ‘œ μ§€μ •ν•˜λŠ” 것은 λ²ˆκ±°λ‘­λ‹€.

κ²Œλ‹€κ°€ ν™˜κ²½ λ³€μˆ˜μ˜ 변경을 좔적 κ΄€λ¦¬ν•˜κ±°λ‚˜ 였λ₯˜κ°€ μžˆμ„ κ²½μš°μ—

λ³€κ²½ μ „μœΌλ‘œ λ°”λ‘œ 되돌릴 수 μžˆλŠ” 방법이 λ§ˆλ•…μΉ˜ μ•Šλ‹€.

λ”°λΌμ„œ μŠ€ν”„λ§ ν”„λ‘œνŒŒμΌμ„ μ΄μš©ν•˜λŠ” 것이 μ„ ν˜Έλœλ‹€.

λŸ°νƒ€μž„ μ‹œμ— ν™œμ„±ν™”λ˜λŠ” ν”„λ‘œνŒŒμΌμ— 따라 μ„œλ‘œ λ‹€λ₯Έ 빈, ꡬ성 클래슀, ꡬ성 속성듀이

적용 λ˜λŠ” λ¬΄μ‹œλ˜λ„λ‘ ν•˜λŠ” 것이 ν”„λ‘œνŒŒμΌμ΄λ‹€.


예λ₯Ό λ“€μ–΄, 개발과 디버깅 λͺ©μ μœΌλ‘œ λ‚΄μž₯ H2 DBλ₯Ό μ‚¬μš©ν•˜κ³ 

타코 ν΄λΌμš°λ“œ μ½”λ“œμ˜ λ‘œκΉ… μˆ˜μ€€μ„ DEBUG둜 μ„€μ •ν•œλ‹€κ³  ν•΄λ³΄μž.

이 경우 개발 μ‹œμ—λŠ” 데이터 μ†ŒμŠ€ 속성을 λ”°λ‘œ μ„€μ •ν•˜μ§€ μ•Šμ•„λ„

μžλ™-κ΅¬μ„±λœ H2 DBλ₯Ό μΆ©λΆ„νžˆ μ‚¬μš©ν•  수 μžˆλ‹€.

그리고 λ‘œκΉ… μˆ˜μ€€μ€ tacos κΈ°λ³Έ νŒ¨ν‚€μ§€μ˜ logging.level.tacos 속성을 application.yml에 DEBUG둜 μ„€μ •ν•˜λ©΄ λœλ‹€.

logging:
  level:
    tacos: DEBUG

κ·ΈλŸ¬λ‚˜ ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” μ™ΈλΆ€μ˜ MySQL DBλ₯Ό μ‚¬μš©ν•˜κ³  λ‘œκΉ… μˆ˜μ€€μ€ WARN으둜 μ„€μ •ν•˜κ³ μž ν•œλ‹€.

이 λ•Œμ—λŠ” ν™˜κ²½λ³„λ‘œ μ ν•©ν•œ 속성듀을 μ„€μ •ν•˜λŠ” ν”„λ‘œνŒŒμΌμ„ μ •μ˜ν•΄μ•Ό ν•œλ‹€.

ν”„λ‘œνŒŒμΌ νŠΉμ • 속성 μ •μ˜ν•˜κΈ°

ν”„λ‘œνŒŒμΌμ— νŠΉμ •ν•œ 속성을 μ •μ˜ν•˜λŠ” ν•œ κ°€μ§€ 방법은 ν”„λ‘œλ•μ…˜ ν™˜κ²½μ˜ μ†μ„±λ“€λ§Œ

ν¬ν•¨ν•˜λŠ” 또 λ‹€λ₯Έ .yml을 μƒμ„±ν•˜λŠ” 것이닀. μ΄λ•Œ 파일 이름은 λ‹€μŒ κ·œμΉ™μ„ 따라야 ν•œλ‹€.

application-[ν”„λ‘œνŒŒμΌ 이름].yml

그러면 ν•΄λ‹Ή ν”„λ‘œνŒŒμΌμ— μ ν•©ν•œ ꡬ성 속성듀을 각 νŒŒμΌμ— μ§€μ •ν•  수 μžˆλ‹€.


λ˜ν•œ YAML κ΅¬μ„±μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλŠ” λ‹€λ₯Έ 방법이 μžˆλ‹€.

μ΄λ•ŒλŠ” ν”„λ‘œνŒŒμΌμ— νŠΉμ •λ˜μ§€ μ•Šκ³  κ³΅ν†΅μœΌλ‘œ μ μš©λ˜λŠ” κΈ°λ³Έ 속성과 ν•¨κ»˜

ν”„λ‘œνŒŒμΌ νŠΉμ • 속성을 application.yml에 μ§€μ •ν•  수 μžˆλ‹€.

logging:
  level:
    tacos: DEBUG

---
spring:
  profiles: prod

  datasource:
    url: jdbc:mysql://localhost/tacocloud
    username: tacouser
    password: tacopassword

logging:
  level:
    tacos: WARN

spring.profilesλ₯Ό μ§€μ •ν•˜μ§€ μ•Šμ€ DEBUG 속성은 λͺ¨λ“  ν”„λ‘œνŒŒμΌμ— κΈ°λ³Έ κ³΅ν†΅μœΌλ‘œ μ μš©λœλ‹€.

ν”„λ‘œνŒŒμΌ ν™œμ„±ν™”ν•˜κΈ°

ν”„λ‘œνŒŒμΌ νŠΉμ • μ†μ„±λ“€μ˜ 섀정은 ν•΄λ‹Ή ν”„λ‘œνŒŒμΌμ΄ ν™œμ„±ν™”λ˜μ–΄μ•Ό μœ νš¨ν•˜λ‹€.

κ·Έλ ‡λ‹€λ©΄ μ–΄λ–»κ²Œ ν”„λ‘œνŒŒμΌμ„ ν™œμ„±ν™”ν•  수 μžˆμ„κΉŒ? spring.profiles.active 속성에 μ§€μ •ν•˜λ©΄ λœλ‹€.

spring:
  profiles:
    active:
      - prod

ν•˜μ§€λ§Œ 이것은 μ—¬λŸ¬ ν™œμ„±ν™” 방법 쀑 κ°€μž₯ μ’‹μ§€ μ•Šμ€ 방법이닀.

ν™œμ„±ν™”λ₯Ό ν•˜λ“œμ½”λ”©ν•˜κ²Œ 되기 λ•Œλ¬Έμ— νŠΉμ • 속성을 개발 속성과 λΆ„λ¦¬μ‹œν‚¬ 수 μ—†λ‹€.

이 방법 λŒ€μ‹  ν™˜κ²½ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•΄μ„œ ν™œμ„±ν™” ν”„λ‘œνŒŒμΌμ„ μ„€μ •ν•˜λŠ” 것이 더 λ‚˜μ€ 방법이닀.

export SPRING_PROFILES_ACTIVE=prod

ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ 해도 ν•΄λ‹Ή 컴퓨터에 λ°°ν¬λ˜λŠ” λͺ¨λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— prod ν”„λ‘œνŒŒμΌμ΄ ν™œμ„±ν™”λœλ‹€λŠ” 단점이 μžˆλ‹€.

μ‹€ν–‰ κ°€λŠ₯ν•œ JAR 파일둜 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•œλ‹€λ©΄, λ‹€μŒκ³Ό 같이 λͺ…λ Ήν–‰ 인자둜 ν™œμ„±ν™” ν”„λ‘œνŒŒμΌμ„ μ„€μ •ν•œλ‹€.

그러면 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ³„λ‘œ ν™œμ„±ν™”λ₯Ό μ„€μ •ν•  수 μžˆλ‹€.

java -jar taco-cloud.jar --spring.profiles.active=prod

spring.profiles.active μ†μ„±μ—λŠ” μ—¬λŸ¬ 개의 ν”„λ‘œνŒŒμΌμ΄ 포함될 수 μžˆλ‹€.

java -jar taco-cloud.jar --spring.profiles.active=prod,audit,ha

YAMLμ—μ„œλŠ” λ‹€μŒκ³Ό 같이 μ§€μ •ν•˜λ©΄ λœλ‹€.

spring:
  profiles:
    active:
      - prod
      - audit
      - ha

ν•œνŽΈ, μŠ€ν”„λ§ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‘°κ±΄λ³„λ‘œ ꡬ성 속성을 μ„€μ •ν•  λ•Œλ§Œ ν”„λ‘œνŒŒμΌμ΄ μœ μš©ν•œ 것은 μ•„λ‹ˆλ‹€.

μ§€κΈˆλΆ€ν„°λŠ” ν™œμ„±ν™” ν”„λ‘œνŒŒμΌμ„ λΉˆμ— μ μš©ν•˜λŠ” 방법을 μ•Œμ•„λ³΄μž.

ν”„λ‘œνŒŒμΌμ„ μ‚¬μš©ν•΄μ„œ μ‘°κ±΄λ³„λ‘œ 빈 μƒμ„±ν•˜κΈ°

μ„œλ‘œ λ‹€λ₯Έ ν”„λ‘œνŒŒμΌ 각각에 μ ν•©ν•œ λΉˆλ“€μ„ μ œκ³΅ν•˜λŠ” 것이 μœ μš©ν•  λ•Œκ°€ μžˆλ‹€.

일반적으둜 μžλ°” ꡬ성 ν΄λž˜μŠ€μ— μ„ μ–Έλœ λΉˆμ€ ν™œμ„±ν™”λ˜λŠ” ν”„λ‘œνŒŒμΌκ³ΌλŠ” λ¬΄κ΄€ν•˜κ²Œ μƒμ„±λœλ‹€.

κ·ΈλŸ¬λ‚˜ νŠΉμ • ν”„λ‘œνŒŒμΌμ΄ ν™œμ„±ν™”λ  λ•Œλ§Œ μƒμ„±λ˜μ–΄μ•Ό ν•˜λŠ” λΉˆλ“€μ΄ μžˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž.

μ΄λ•Œ @Profile μ• λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄ μ§€μ •λœ ν”„λ‘œνŒŒμΌμ—λ§Œ μ ν•©ν•œ λΉˆλ“€μ„ 생성할 수 μžˆλ‹€.


예λ₯Ό λ“€μ–΄, TacoCloudApplicationμ—λŠ” CommandLineRunner 빈이 μ„ μ–Έλ˜μ–΄ μžˆλ‹€.

그리고 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹œμž‘λ  λ•Œλ§ˆλ‹€ μ‹μžμž¬ 데이터λ₯Ό λ‚΄μž₯ DB에 λ‘œλ“œν•˜κΈ° μœ„ν•΄ CommandLineRunner 빈이 μ‚¬μš©λœλ‹€.

ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œλŠ” λΉ„ν™œμ„±ν™”ν•˜λŠ” 것이 λ‚˜μ„ 것이닀.

μ΄λ•Œ CommandLineRunner 빈 λ©”μ„œλ“œμ— @Profile을 μ§€μ •ν•˜λ©΄ ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œ μ‹μžμž¬ 데이터가 λ‘œλ“œλ˜λŠ” 것을 λ°©μ§€ν•  수 μžˆλ‹€.

@Bean
@Profile("dev")
public CommandLineRunner dataLoader(IngredientRepository repo) {
    return new CommandLineRunner() {
        @Override
        public void run(String... args) throws Exception {
            repo.save(new Ingredient("FLTO", "Flour Tortilla", Ingredient.Type.WRAP));
            repo.save(new Ingredient("COTO", "Corn Tortilla", Ingredient.Type.WRAP));
            repo.save(new Ingredient("GRBF", "Ground Beef", Ingredient.Type.PROTEIN));
            repo.save(new Ingredient("CARN", "Carnitas", Ingredient.Type.PROTEIN));
            repo.save(new Ingredient("TMTO", "Diced Tomatoes", Ingredient.Type.VEGGIES));
            repo.save(new Ingredient("LETC", "Lettuce", Ingredient.Type.VEGGIES));
            repo.save(new Ingredient("CHED", "Cheddar", Ingredient.Type.CHEESE));
            repo.save(new Ingredient("JACK", "Monterrey Jack", Ingredient.Type.CHEESE));
        }
    };
}

λ˜λŠ” dev ν”„λ‘œνŒŒμΌμ΄λ‚˜ qa ν”„λ‘œνŒŒμΌ 쀑 ν•˜λ‚˜κ°€ ν™œμ„±ν™”λ  λ•Œμ—λŠ” μ›ν•˜λŠ” ν”„λ‘œνŒŒμΌμ„ μΆ”κ°€ν•˜λ©΄ λœλ‹€.

@Profile({"dev", "qa"})

ν˜Ήμ€ μ΄λ ‡κ²Œ μ§€μ •ν•  μˆ˜λ„ μžˆλ‹€.

@Profile("!prod")

@Profile은 @Configuration이 μ§€μ •λœ 클래슀 전체에 λŒ€ν•΄ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

예λ₯Ό λ“€μ–΄, DevelopmentConfigλΌλŠ” μ΄λ¦„μ˜ ꡬ성 클래슀둜

CommandLineRunner λΉˆμ„ μ£Όμž…ν•  λ•Œ λ‹€μŒκ³Ό 같이 @Profile을 μ§€μ •ν•  수 μžˆλ‹€.

package tacos;
/*
 * @USER JungHyun
 * @DATE 2020-07-31
 * @DESCRIPTION
 */

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.security.crypto.password.PasswordEncoder;
import tacos.data.IngredientRepository;
import tacos.data.UserRepository;

@Profile({"!prod", "!qa"})
public class DevelopmentConfig {
    @Bean
    public CommandLineRunner dataLoader(IngredientRepository repo, UserRepository userRepo, PasswordEncoder encoder) {
        ...
    }
}

이 κ²½μš°λŠ” prod ν”„λ‘œνŒŒμΌκ³Ό qa ν”„λ‘œνŒŒμΌ λͺ¨λ‘ ν™œμ„±ν™”λ˜μ§€ μ•Šμ„ λ•Œλ§Œ CommandLineRunner 빈이 μƒμ„±λœλ‹€.