์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ์‚ฌ์šฉ ๋ฐฉ๋ฒ• (Environment)

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

728x90

 

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ˆ˜, ์ปค๋งจ๋“œ ๋ผ์ธ ์˜ต์…˜ ์ธ์ˆ˜, ์Šคํ”„๋ง ํ†ตํ•ฉ) (tistory.com)

 

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ˆ˜, ์ปค๋งจ๋“œ ๋ผ์ธ ์˜ต์…˜ ์ธ์ˆ˜, ์Šคํ”„๋ง ํ†ตํ•ฉ)

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜, ์ž๋ฐ” ์‹œ์Šคํ…œ ์†์„ฑ) (tistory.com) ์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜, ์ž๋ฐ” ์‹œ์Šคํ…œ ์†์„ฑ) 0๏ธโƒฃ ์™ธ๋ถ€ ์„ค์ •์ด๋ž€ ? ๋ณดํ†ต ์‹ค๋ฌด์—์„œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ๋Œ€๋ถ€๋ถ„ ํšŒ์‚ฌ์—

hyejin.tistory.com

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (์™ธ๋ถ€ ๋ฐ์ดํ„ฐ) (tistory.com)

 

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (์™ธ๋ถ€ ๋ฐ์ดํ„ฐ)

์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜, ์ž๋ฐ” ์‹œ์Šคํ…œ ์†์„ฑ) (tistory.com) ์Šคํ”„๋ง ์™ธ๋ถ€ ์„ค์ • ๋ฐฉ๋ฒ• (OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜, ์ž๋ฐ” ์‹œ์Šคํ…œ ์†์„ฑ) 0๏ธโƒฃ ์™ธ๋ถ€ ์„ค์ •์ด๋ž€ ? ๋ณดํ†ต ์‹ค๋ฌด์—์„œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ๋Œ€๋ถ€๋ถ„ ํšŒ์‚ฌ์—

hyejin.tistory.com

์Šคํ”„๋ง์—์„œ ์™ธ๋ถ€ ์„ค์ • ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋ก  4๊ฐ€์ง€ ์ •๋„ ์žˆ๋‹ค. 

- OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜

- ์ž๋ฐ” ์‹œ์Šคํ…œ ์†์„ฑ 

- ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ˆ˜ 

- ์„ค์ • ๋ฐ์ดํ„ฐ (application.properties) 

 

๊ทธ๋ฆฌ๊ณ  ์ด ์™ธ๋ถ€ ์„ค์ •์„ ์ฝ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ง€๊ธˆ๊นŒ์ง€๋Š” Environment ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค๋Š”๋ฐ ์Šคํ”„๋ง์€ Environment ๋ง๊ณ ๋„ 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ๋” ์ œ๊ณตํ•œ๋‹ค. 

 

* ์™ธ๋ถ€ ์„ค์ • ์กฐํšŒ ๋ฐฉ๋ฒ• 

- Environment 

- @Value 

- @ConfigurationProperties : ํƒ€์ž… ์•ˆ์ „ํ•œ ์„ค์ • ์†์„ฑ 

 

 

 

0๏ธโƒฃ ์™ธ๋ถ€ ์„ค์ • ์กฐํšŒ ๋ฐฉ๋ฒ• : Environment 

์™ธ๋ถ€ ์„ค์ •๋“ค์€ ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” Environment๋ฅผ ํ†ตํ•ด์„œ ์ผ๊ด€๋œ ๋ฐฉ์‹์œผ๋กœ ๊ฐ’์„ ์กฐํšŒํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

MyDataSource 

@Slf4j
public class MyDataSource
{
   private String url;
   private String username;
   private String password;
   private int maxConnection;
   private Duration timeout;
   private List<String> options;
   
   public MyDataSource(String url, String username, String password,
         int maxConnection, Duration timeout, List<String> options)
   {
      this.url = url;
      this.username = username;
      this.password = password;
      this.maxConnection = maxConnection;
      this.timeout = timeout;
      this.options = options;
   }
   
   @PostConstruct
   public void init()
   {
      // ์„ค์ •๋œ ๊ฐ’ ์ถœ๋ ฅ
      log.info("url={}", url);
      log.info("username={}", username);
      log.info("password={}", password);
      log.info("maxConnection={}", maxConnection);
      log.info("timeout={}", timeout);
      log.info("options={}", options);
      
   }
}

์˜ˆ์ œ๋Š” ํ•„์š”ํ•œ ์†์„ฑ๋“ค(url, username...) ๋“ค์„ ์™ธ๋ถ€ ์„ค์ •๊ฐ’์œผ๋กœ ์ฑ„์šด ๋‹ค์Œ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค. 

(์‹ค์ œ DB์— ์ ‘๊ทผํ•˜์ง€๋Š” ์•Š์Œ, ๋‹จ์ˆœ ์˜ˆ์ œ) 

 

@PostConstruct

: ์„ค์ •๋œ ๊ฐ’๋“ค์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ 

 

 

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.properties์— ์„ค์ •ํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•œ๋‹ค. 

 

๐Ÿ‘พ ๊ทธ๋ฆฌ๊ณ  application.properties์—์„œ๋Š” ๋‚™ํƒ€ ํ‘œ๊ธฐ๋ฒ•์ด ์•„๋‹Œ ์ผ€๋ฐฅ ํ‘œ๊ธฐ๋ฒ•์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  properties์—๋Š” ์ผ€๋ฐฅ ํ‘œ๊ธฐ๋ฒ•์„ ๊ถŒ์žฅํ•œ๋‹ค.

์ผ€๋ฐฅ ํ‘œ๊ธฐ๋ฒ•์€ ์†Œ๋ฌธ์ž - (dash)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. 

 

 

MyDataSourceEnvConfig

@Slf4j
@Configuration
public class MyDataSourceEnvConfig
{
   private final Environment environment;
   
   public MyDataSourceEnvConfig(Environment environment)
   {
      this.environment = environment;
   }
   
   @Bean
   public MyDataSource myDataSource()
   {
      String url = environment.getProperty("my.datasource.url");
      String username = environment.getProperty("my.datasource.username");
      String password = environment.getProperty("my.datasource.password");
      int maxConnection = environment.getProperty("my.datasource.etc.max-connection", Integer.class);
      Duration timeout = environment.getProperty("my.datasource.etc.timeout", Duration.class);
      List options = environment.getProperty("my.datasource.etc.options", List.class);
      
      return new MyDataSource(url, username, password, maxConnection, timeout, options);
   }
}

MyDatasource๋ฅผ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ • ํŒŒ์ผ์ด๋‹ค. 

Environment๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™ธ๋ถ€ ์„ค์ •์„ ์–ด๋–ค ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ๋˜ ์ผ๊ด€๋œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด์„œ ์™ธ๋ถ€ ์„ค์ •์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. 

Environment.getProperty(key, type) ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํƒ€์ž… ์ •๋ณด๋ฅผ ์ฃผ๋ฉด ํ•ด๋‹น ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค.  (์Šคํ”„๋ง์€ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ ๊ธฐ๋ณธ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.) 

 

 

@Import(MyDataSourceEnvConfig.class)
@SpringBootApplication(scanBasePackages = "hello.datasource")
public class ExternalReadApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExternalReadApplication.class, args);
    }

}

MyDataSourceEnvConfig ์„ค์ • ํŒŒ์ผ์„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ @Import ๋กœ ์ถ”๊ฐ€๋ฅผ ํ•ด์ฃผ๊ณ , 

@SpringBootApplication(scanBasePackages = "hello.datasource") ๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋ฒ”์œ„๋ฅผ ์ œํ•œํ–ˆ๋‹ค. 

(์™œ๋ƒํ•˜๋ฉด ๋’ค์— ์˜ˆ์ œ๋ฅผ ํ•˜๋ฉด์„œ @Import ๋กœ ์„ค์ • ์ •๋ณด๋ฅผ ๊ณ„์† ๋ณ€๊ฒฝํ•  ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ • ์ •๋ณด๋ฅผ ๋ฐ”๊พธ๋ฉด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ hello.config ๋Š” ์ปดํฌ๋„ŒํŠธ ์Šค์บ”์„ ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ์ œํ•œํ–ˆ๋‹ค. ) 

 

 

๐Ÿ’Œ application.properties์— ํ•„์š”ํ•œ ์™ธ๋ถ€ ์„ค์ • ๊ฐ’๋“ค์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๊ทธ ๋‹ค์Œ Environment ๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ๊ฐ’๋“ค์„ ์กฐํšŒํ•ด์„œ MyDataSource๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. 

๊ทผ๋ฐ Environment๋ฅผ ํ†ตํ•ด์„œ ์™ธ๋ถ€ ์„ค์ • ๊ฐ’๋“ค์„ ์กฐํšŒํ•  ๋•Œ๋Š” getProperty๋ฅผ ํ†ตํ•ด์„œ ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ ๊ณ„์† ๊บผ๋‚ด๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. 

 

 

 

 

1๏ธโƒฃ ์™ธ๋ถ€ ์„ค์ • ์กฐํšŒ ๋ฐฉ๋ฒ• : @Value 

์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” @Value ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Enviroment๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ getProperty ์ด๋Ÿฐ ๋ฐ˜๋ณต๋˜๋Š” ๊ณผ์ •์ด ์—†์–ด๋„ ์™ธ๋ถ€ ์„ค์ •๊ฐ’์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. 

 

MyDataSourceValueConfig

@Slf4j
@Configuration
public class MyDataSourceValueConfig
{
   
   @Value("${my.datasource.url}")
   private String url;
   @Value("${my.datasource.username}")
   private String username;
   @Value("${my.datasource.password}")
   private String password;
   @Value("${my.datasource.etc.max-connection}")
   private int maxConnection;
   @Value("${my.datasource.etc.timeout}")
   private Duration timeout;
   @Value("${my.datasource.etc.options}")
   private List<String> options;
   
   @Bean
   public MyDataSource myDataSource1()
   {
       return new MyDataSource(url, username, password, maxConnection, timeout, options);
   }
   
   // @Value๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
   @Bean
   public MyDataSource myDataSource2(
         @Value("${my.datasource.url}") String url,
         @Value("${my.datasource.username}") String username,
         @Value("${my.datasource.password}") String password,
         @Value("${my.datasource.etc.max-connection}") int maxConnection,
         @Value("${my.datasource.etc.timeout}") Duration timeout,
         @Value("${my.datasource.etc.options}") List<String> options
         )
   {
      return new MyDataSource(url, username, password, maxConnection, timeout, options);
   }
}

@Value("${}") {} ์•ˆ์— ํ‚ค ๊ฐ’์„ ๋„ฃ์–ด์คŒ๋…€ ์›ํ•˜๋Š” ๊ฐ’์„ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. 

MyDataSource1๊ณผ MyDataSource2์—์„œ๋„ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, @Value๋Š” ํ•„๋“œ์— ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ํŒŒ๋ผ๋ฏธํ„ฐ์— ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. 

 

* ๊ธฐ๋ณธ๊ฐ’ 

๋งŒ์•ฝ @Value๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๊ฐ’์ด ์—†๋‹ค๋ฉด @Value("${my.datasource.max-connection:1}")  : ๋’ค์— ๊ธฐ๋ณธ ๊ฐ’์„ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

 

๐Ÿ’Œ ์ด๋ฒˆ์—๋Š” application.properties์— ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด๋‘๊ณ , @Value ๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ๊ฐ’๋“ค์„ ์ฝ์–ด์„œ MyDataSource๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. 

@Value๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์—ญ์‹œ ํŽธ๋ฆฌํ•˜์ง€๋งŒ ๋ณด๋ฉด ์„ค์ • ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ @Value๋กœ ํ‚ค ๊ฐ’์„ ์ž…๋ ฅํ•˜๊ณ  ์ฃผ์ž… ๋ฐ›์•„์•ผํ•˜๋Š” ๋ถ€๋ถ„์€ ์—ญ์‹œ๋‚˜ ๋ฒˆ๊ฑฐ๋กญ๋‹ค. 

 

 

 

2๏ธโƒฃ ์™ธ๋ถ€ ์„ค์ • ์กฐํšŒ ๋ฐฉ๋ฒ• : @ConfigurationProperties 

Type-safe Configuration Properties 

: ์Šคํ”„๋ง์€ ํƒ€์ž… ์•ˆ์ „ํ•œ ์„ค์ • ์†์„ฑ์ด๋ผ๊ณ  ์™ธ๋ถ€ ์„ค์ •์˜ ๋ฌถ์Œ ์ •๋ณด๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. 

์™œ ํƒ€์ž… ์•ˆ์ „ํ•œ ์„ค์ • ์†์„ฑ์ด๋ผ๊ณ  ํ•˜๋Š๋ƒ ํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Ÿฌ๋ฉด ์‹ค์ˆ˜๋กœ ์ž˜๋ชป๋œ ํƒ€์ž…์ด ๋“ค์–ด์˜ค๋Š” ๋ฌธ์ œ๋ฅผ ๊ธˆ๋ฐฉ ๊ฐ์ง€ํ•˜๊ณ  ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

 

MyDataSourcePropertiesV1

@Data
@ConfigurationProperties("my.datasource")
public class MyDataSourcePropertiesV1
{
   private String url;
   private String username;
   private String password;
   private Etc etc;
   
   @Data
   public static class Etc {
      private int maxConnection;
      private Duration timeout;
      private List<String> options = new ArrayList<>();
   }
}

application.properties์— ์„ค์ • ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋ฉด ํ•˜๋‚˜ํ•˜๋‚˜ ๋ถ„๋ฆฌ๋œ ๊ฐ’๋“ค์ด ์•„๋‹ˆ๋ผ my.datasource๋กœ ๋ฌถ์—ฌ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

MyDataSourcePropertiesV1์€ ์™ธ๋ถ€ ์„ค์ • ์ •๋ณด๋ฅผ ์ฃผ์ž… ๋ฐ›์„ ๊ฐ์ฒด๋กœ ๊ฐ ํ•„๋“œ๋ฅผ ์™ธ๋ถ€ ์„ค์ • ํ‚ค ๊ฐ’์— ๋งž์ถ”์–ด ์ƒ์„ฑํ•ด๋‘”๋‹ค. 

 

@ConfigurationProperties ์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์œผ๋ฉด ์™ธ๋ถ€ ์„ค์ •์„ ์ฃผ์ž… ๋ฐ›๋Š” ๊ฐ์ฒด๋ผ๋Š” ๋œป์œผ๋กœ ๊ฐ์ฒด๋กœ ๋ฌถ์„ ์‹œ์ž‘์ (?)์ธ my.datasource๋ฅผ ํ‚ค ๊ฐ’์œผ๋กœ ์ ์–ด์ค€๋‹ค. 

 

 

MyDataSourceConfigV1

@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV1.class)
public class MyDataSourceConfigV1
{
   private final MyDataSourcePropertiesV1 propertiesV1;
   
   public MyDataSourceConfigV1(MyDataSourcePropertiesV1 propertiesV1)
   {
      this.propertiesV1 = propertiesV1;
   }
   
   @Bean
   public MyDataSource dataSource()
   {
      return new MyDataSource(propertiesV1.getUrl(),
                        propertiesV1.getUsername(),
                        propertiesV1.getPassword(),
                        propertiesV1.getEtc().getMaxConnection(),
                        propertiesV1.getEtc().getTimeout(),
                        propertiesV1.getEtc().getOptions());
   }
}

@EnableConfigurationProperties(MyDataSourcePropertiesV1.class)

: ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ์Šคํ”„๋ง์—๊ฒŒ MyDataSourcePropertiesV1์„ ConfigurationProperties๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๊ณ  ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค. 

๊ทธ๋Ÿฌ๋ฉด ์ด ํด๋ž˜์Šค๋Š” ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜๊ณ  ํ•„์š”ํ•œ ๊ณณ์—์„œ ์ฃผ์ž…๋ฐ›์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

๐Ÿ’Œ @ConfigurationProperties๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž… ์•ˆ์ „ํ•œ ์„ค์ • ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

๋งŒ์•ฝ max-connection์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ dkafj ๋ญ ์ด๋Ÿฐ ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐ”๋‹ค๊ณ  ํ•˜๋ฉด ์‹คํ–‰ํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ํƒ€์ž…์ด ๋‹ค๋ฅด๋‹ค๊ณ  ์•Œ๋ ค์ค€๋‹ค. 

๋”ฐ๋ผ์„œ ์‹ค์ˆ˜๋กœ ์ˆซ์ž๋ฅผ ๋„ฃ์–ด์•ผํ•˜๋Š” ๊ณณ์— ๋ฌธ์ž๋ฅผ ๋„ฃ๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์ด๋ฒˆ ๋ฐฉ๋ฒ•์€ application.properties์— ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ๋„ฃ์–ด๋‘๊ณ , @ConfigurationProperties๋ฅผ ์‚ฌ์šฉํ•ด์„œ MyDataSourcePropertivesV1 ์— ์™ธ๋ถ€ ์„ค์ • ๊ฐ’๋“ค์„ ์„ค์ •ํ•ด MyDataSource๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. 

 

 

* ๊ทธ๋ฆฌ๊ณ  ์ด๋•Œ application.properties๋Š” ์ผ€๋ฐฅ ํ‘œ๊ธฐ๋ฒ•์ด๊ณ , MyDatasourcePropertiesV1์—์„œ๋Š” ๋‚™ํƒ€ ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ maxConnection์„ ๋‹ค๋ฃจ๊ณ  ์ž‡๋Š”๋ฐ ์Šคํ”„๋ง์€ ์ผ€๋ฐฅ ํ‘œ๊ธฐ๋ฒ•์„ ๋‚™ํƒ€ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ์ค‘๊ฐ„์—์„œ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์‹ ๊ฒฝ์“ธ ํ•„์š”๋Š” ์—†๋‹ค. 

 

 

@ConfigurationPropertiesScan

@ConfigurationProperties๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ๋“ฑ๋กํ•  ๋•Œ๋Š” @EnableConfigurationProperties๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜์ง€๋งŒ ๋งŒ์•ฝ ํŠน์ • ๋ฒ”์œ„๋กœ ์ž๋™ ๋“ฑ๋กํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” ๋ฉ”์ธ ๋ฉ”์„œ๋“œ์— @ConfigurationPropertiesScan ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

@ConfigurationPropertiesScan
@SpringBootApplication(scanBasePackages = "hello.datasource")
public class ExternalReadApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExternalReadApplication.class, args);
    }

}

 

 

MyDataSourcePropertiesV2

@Getter
@ConfigurationProperties("my.datasource")
public class MyDataSourcePropertiesV2
{
   private String url;
   private String username;
   private String password;
   private Etc etc;
   
   public MyDataSourcePropertiesV2(String url, String username, String password, Etc etc)
   {
      this.url = url;
      this.username = username;
      this.password = password;
      this.etc = etc;
   }
   
   @Getter
   public static class Etc {
      private int maxConnection;
      private Duration timeout;
      private List<String> options = new ArrayList<>();
      
      public Etc(int maxConnection, Duration timeout, @DefaultValue("DEFAULT") List<String> options)
      {
         this.maxConnection = maxConnection;
         this.timeout = timeout;
         this.options = options;
      }
   }
}

์œ„์˜ MyDatasourcePropertiesV1์€ Getter, Setter๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ฝ๊ณ  ์“ฐ๊ณ  ํ•˜๊ณ  ์žˆ๋Š”๋ฐ Setter ๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์œผ๋กœ ๊ฐ€์ ธ์™”๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. 

๋ณดํ†ต ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•œ๋ฒˆ ์กฐํšŒํ•ด์„œ ๊ฐ’์„ ์ž…๋ ฅํ•˜๊ณ  ๋‚˜๋ฉด ๋” ์ด์ƒ ๋ณ€๊ฒฝํ•  ์ผ์ด ์—†๋‹ค๋Š” ๊ฑด๋ฐ Setter๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋Š ํฌ์ธํŠธ์—์„œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋ ์ง€ ๋ชจ๋ฅธ๋‹ค๋Š” ์œ„ํ—˜์ด ์žˆ๋‹ค. 

 

 

๋”ฐ๋ผ์„œ Getter, Setter ๋ฐฉ์‹์ด ์•„๋‹Œ  MyDatasourcePropertiesV2 ์ฒ˜๋Ÿผ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ๊ฒ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค. 

(๋Œ€์‹  ๊ฐ์ฒด๋ฅผ ์กฐํšŒํ•  ์ˆ˜๋Š” ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— @Getter๋งŒ ๋‚จ๊ฒจ๋‘”๋‹ค. )

 

@DefaultValue

: ํ•ด๋‹น ๊ฐ’์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ๊ธฐ๋ณธ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ง€์ •ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ 

@DefaultValue("DEFAULT") List<String> options ๋กœ ํ•ด์ฃผ๋ฉด options์— ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” DEFAULT ๋ฅผ ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. 

 

 

MyDataSourceConfigV2

@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV2.class)
public class MyDataSourceConfigV2
{
   private final MyDataSourcePropertiesV2 propertiesV2;
   
   public MyDataSourceConfigV2(MyDataSourcePropertiesV2 propertiesV2)
   {
      this.propertiesV2 = propertiesV2;
   }
   
   @Bean
   public MyDataSource dataSource()
   {
      return new MyDataSource(propertiesV2.getUrl(),
                        propertiesV2.getUsername(),
                        propertiesV2.getPassword(),
                        propertiesV2.getEtc().getMaxConnection(),
                        propertiesV2.getEtc().getTimeout(),
                        propertiesV2.getEtc().getOptions());
   }
}

MyDataSourceProperties๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ @EnableConfigurationProperties ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค. 

 

 

๐Ÿ’Œ MyDataSourcePropertiesV2์—์„œ๋ณด๋ฉด application.properties ์—์„œ ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๊ทธ ๋‹ค์Œ @ConfigurationProperties ์˜ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ†ตํ•ด์„œ ์ด ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ์ฝ์–ด์˜จ๋‹ค. Setter๊ฐ€ ์•„๋‹Œ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด์„œ ์™ธ๋ถ€ ์„ค์ • ๊ฐ’์„ ์ฝ์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์ด์ œ ์ค‘๊ฐ„์— ๋ณ€๊ฒฝ๋  ์ผ์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค! 

 

 

 

3๏ธโƒฃ @ConfigurationProperties ๊ฒ€์ฆ 

@ConfigurationProperties ํƒ€์ž… ์•ˆ์ „ ์„ค์ • ์†์„ฑ์„ ํ†ตํ•ด์„œ ์™ธ๋ถ€ ์„ค์ •์„ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด์„œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ˆซ์ž๊ฐ€ ๋“ค์–ด๊ฐ€์•ผํ•˜๋Š” ๋ถ€๋ถ„์— ๋ฌธ์ž๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ  ์ด๋Ÿฐ ๋ฌธ์ œ๋Š” ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ˆซ์ž์˜ ๋ฒ”์œ„๋‚˜ ๋ฌธ์ž ๊ธธ์ด์— ๋Œ€ํ•ด์„œ๋Š” ๊ฒ€์ฆ์ด ์–ด๋ ต๋‹ค. 

(๋ฌผ๋ก  ์ฝ”๋“œ๋กœ ์ง์ ‘ ์ž‘์„ฑํ•ด์„œ ๊ฒ€์ฆํ•   ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ํ•˜๋‚˜ํ•˜๋‚˜ ๊ฒ€์ฆ ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์•ผ ํ•ด์„œ ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์ฝ”๋“œ๋„ ์ง€์ €๋ถ„ํ•ด์ง„๋‹ค. 

๋Œ€์‹  ์ž๋ฐ” ๋นˆ ๊ฒ€์ฆ๊ธฐ (Java Bean Validation) ์„ ํ†ตํ•ด์„œ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.) 

 

implementation 'org.springframework.boot:spring-boot-starter-validation'

์šฐ์„  build.gradle์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  reload ํ•ด์ค€๋‹ค. 

 

 

MyDataSourcePropertiesV3

@Getter
@ConfigurationProperties("my.datasource")
@Validated
public class MyDataSourcePropertiesV3
{
   @NotEmpty
   private String url;
   @NotEmpty
   private String username;
   @NotEmpty
   private String password;
   private Etc etc;
   
   public MyDataSourcePropertiesV3(String url, String username, String password, Etc etc)
   {
      this.url = url;
      this.username = username;
      this.password = password;
      this.etc = etc;
   }
   
   @Getter
   public static class Etc {
      @Min(1) @Max(999)
      private int maxConnection;
      @DurationMin(seconds = 1)
      @DurationMax(seconds = 60)
      private Duration timeout;
      private List<String> options = new ArrayList<>();
      
      public Etc(int maxConnection, Duration timeout, List<String> options)
      {
         this.maxConnection = maxConnection;
         this.timeout = timeout;
         this.options = options;
      }
   }
}

- url, username, password์—๋Š” @NotEmpty๋ฅผ ์ค˜์„œ ํ•ญ์ƒ ๊ฐ’์ด ์žˆ๋„๋ก ํ•œ๋‹ค. 

- maxConnection ์—๋Š” @Min(1), @Max(999)๋กœ ๊ฐ’์„ ์ œํ•œํ•ด์„œ ์ตœ์†Œ 1, ์ตœ๋Œ€ 999๋กœ ๊ฐ’์„ ํ—ˆ์šฉํ•ด ๊ทธ ๊ฐ’์„ ๋„˜๊ฑฐ๋‚˜ ๋ถ€์กฑํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚˜๋„๋ก ํ•œ๋‹ค. 

- timeout์—๋Š” @DurationMin(seconds =1), @DurationMax(seconds = 60) ์„ ์ค˜์„œ ์ตœ์†Œ 1์ดˆ, ์ตœ๋Œ€ 60์ดˆ๋กœ ์ œํ•œํ•œ๋‹ค. 

 

 

MyDataSourceConfigV3

@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV3.class)
public class MyDataSourceConfigV3
{
   private final MyDataSourcePropertiesV3 propertiesV3;
   
   public MyDataSourceConfigV3(MyDataSourcePropertiesV3 propertiesV3)
   {
      this.propertiesV3 = propertiesV3;
   }
   
   @Bean
   public MyDataSource dataSource()
   {
      return new MyDataSource(propertiesV3.getUrl(),
                        propertiesV3.getUsername(),
                        propertiesV3.getPassword(),
                        propertiesV3.getEtc().getMaxConnection(),
                        propertiesV3.getEtc().getTimeout(),
                        propertiesV3.getEtc().getOptions());
   }
}

์ด๋ ‡๊ฒŒ ๊ฐ’ ์ œํ•œ์„ ํ•˜๊ณ  ๋‚˜์„œ ์‹คํ–‰ํ•  ๋•Œ application.properties์— maxConnection์„ ๋งŒ์•ฝ 0์œผ๋กœ ์‹ค์ˆ˜๋กœ ์„ค์ •์„ ํ–ˆ๋‹ค๋ฉด 

์ด๋Ÿฐ์‹์œผ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

 

 

 

๐Ÿ“š ConfigurationProperties  ์ •๋ฆฌ 

@ConfigurationProperties ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์™ธ๋ถ€ ์„ค์ •์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์„œ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์™ธ๋ถ€ ์„ค์ •์„ ํƒ€์ž… ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉฐ ๊ฒ€์ฆ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90