지금까지 외부 설정을 어떻게 하는지 자세히 알아봤으니 이제 그렇게 설정한 값들을 사용해보는 방법도 익혀보자.
크게 세가지 방식이 존재한다.
- Environment
- @Value - 값 주입
- @ConfigurationProperties - 타입 안전한 설정 속성
Environment는 이미 한번 다뤄본 적이 있다. 그래도 한번 더 사용해서 어떤점이 불편해서 새로운 방식이 나온건지도 알아보자.
외부설정 사용 - Environment
우선, 가상의 DataSource를 하나 만들고, 여기에 필요한 속성들을 외부 설정값으로 채운 다음 스프링 빈으로 등록할 것이다.
application.yml
my:
datasource:
url: local.db.com
username: username
password: password
etc:
max-connection: 1
timeout: 3500ms
options: CACHE,ADMIN
MyDataSource
package hello.datasource;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import java.time.Duration;
import java.util.List;
@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);
}
}
MyDataSourceEnvConfig
package hello.config;
import hello.datasource.MyDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import java.time.Duration;
import java.util.List;
@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");
Integer maxConnection = environment.getProperty("my.datasource.etc.max-connection", Integer.class);
Duration duration = environment.getProperty("my.datasource.etc.timeout", Duration.class);
List<String> options = environment.getProperty("my.datasource.etc.options", List.class);
return new MyDataSource(url, username, password, maxConnection, duration, options);
}
}
MyDataSourceEnvConfig 여기에서 MyDataSource를 빈으로 등록한 다음 필요한 값들을 Environment를 통해 외부 설정으로부터 가져온다. 이 Environment는 어떤 외부 설정이던 상관없이 가져올 수 있게 스프링이 제공해주는 아주 좋은 추상화된 객체이므로 위 코드처럼 값들을 가져올 수 있다.
한번 서버를 실행해보면 결과는 다음과 같다.
보이는 것처럼 @PostConstruct에 의해 호출된 데이터값들이 잘 보여진다.
근데, 이 방식은 어떤 단점이 있는가하면, 이 Environment를 직접 주입받는 것 자체에 있다. 주입을 직접 받는것도 불편하지만 받은 객체를 통해 계속해서 .getProperty()를 호출해서 꺼내와야만 한다. 이것을 반복하는 게 단점이다. 스프링은 @Value를 통해서 외부 설정값을 주입 받는 더욱 편리한 기능을 제공한다.
@Value
이 방법은 스프링이 외부 설정값을 편리하게 주입받게 해주는 방법이다. (사실 이 방법도 내부적으로는 Environment를 사용한다)
MyDataSourceValueConfig
package hello.config;
import hello.datasource.MyDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.List;
@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를 사용해서 외부 설정값을 "${}" 이 안에 가져올 수 있다.
근데, 이 방법은 다른 방식도 있다. 파라미터로 받는 방법도 있는데 다음과 같이 사용하면 된다.
MyDataSourceValueConfig
package hello.config;
import hello.datasource.MyDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.List;
@Slf4j
@Configuration
public class MyDataSourceValueConfig {
@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("${my.datasource.etc.max-connection:2}")
private int maxConnection;
이렇게 :2 라고 해두면 없는 경우 기본값을 2로 받아오겠다는 의미가 된다.
그래서 이렇게 간단하게 가져올 수는 있다만 이 방법 역시 하나하나 외부 설정 정보의 키 값을 입력받고 주입 받아와야 하는 부분이 번거롭다. 그리고 설정 데이터를 보면 하나하나 분리되어 있는 게 아니라 정보의 묶음으로 되어 있다. my.datasource.xxx 이렇게 말이다.
그 말은 이 부분을 객체로 변환해서 사용할 수 있다면 더 편리하고 더 좋을 것이다. 그 방법을 알아보자.
외부 설정 사용 - @ConfigurationProperties
이번에는 외부 설정 값을 객체로 가져올 수 있는 방법에 대해 알아보자.
우선, 객체로 가져오려면 객체가 필요하다.
MyDataSourcePropertiesV1
package hello.datasource;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@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<>();
}
}
이 객체를 보면, @ConfigurationProperties("my.datasource") 애노테이션이 있다. 이 애노테이션을 사용하면, .yml 파일이나 .properties 파일에 값을 등록한 `my.datasource`키에 대한 값을 객체로 변환해서 읽어오게된다.
그리고 그 중에 url, username, password는 바로 접근할 수 있지만, max-connection, timeout, options는 etc라는 키 하위에 존재한다. 다음 application.yml 파일을 비교해서 봐보자.
my:
datasource:
url: local.db.com
username: local_user
password: local_pw
etc:
max-connection: 1
timeout: 60s
options: LOCAL, CACHE
그래서, 내부 클래스로 이 값들 또한 객체로 받아준다. 이렇게 설정하고 나면 Configuration 클래스가 필요하다.
MyDataSourcePropertiesConfigV1
package hello.config;
import hello.datasource.MyDataSource;
import hello.datasource.MyDataSourcePropertiesV1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV1.class)
public class MyDataSourcePropertiesConfigV1 {
private final MyDataSourcePropertiesV1 properties;
public MyDataSourcePropertiesConfigV1(MyDataSourcePropertiesV1 properties) {
this.properties = properties;
}
@Bean
public MyDataSource dataSource() {
return new MyDataSource(
properties.getUrl(),
properties.getUsername(),
properties.getPassword(),
properties.getEtc().getMaxConnection(),
properties.getEtc().getTimeout(),
properties.getEtc().getOptions());
}
}
이 파일에서 중요한 부분은 @EnableConfigurationProperties(MyDataSourcePropertiesV1.class) 애노테이션이다.
이 애노테이션을 달아서, MyDataSourcePropertiesV1 클래스를 통해 외부 설정값들을 클래스 형태의 빈으로 등록한다.
빈으로 등록했으니, 주입하면 된다. 주입하면 MyDataSource를 빈으로 등록하기 위한 값을 사용하면 된다.
이제 @Import 애노테이션을 변경 후 실행해보자. 정상적으로 실행될 것이다.
ExternalReadApplication
package hello;
import hello.config.MyDataSourceEnvConfig;
import hello.config.MyDataSourcePropertiesConfigV1;
import hello.config.MyDataSourceValueConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.Import;
//@Import(MyDataSourceEnvConfig.class)
//@Import(MyDataSourceValueConfig.class)
@Import(MyDataSourcePropertiesConfigV1.class)
@SpringBootApplication(scanBasePackages = "hello.datasource")
public class ExternalReadApplication {
public static void main(String[] args) {
SpringApplication.run(ExternalReadApplication.class, args);
}
}
실행결과
2024-06-22T15:11:34.007+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : Starting ExternalReadApplication using Java 17.0.9 with PID 1827 (/Users/choichiwon/Spring/external-read/out/production/classes started by choichiwon in /Users/choichiwon/Spring/external-read)
2024-06-22T15:11:34.008+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : No active profile set, falling back to 1 default profile: "default"
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : url=local.db.com
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : username=local_user
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : password=local_pw
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : maxConnection=1
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : timeout=PT1M
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : options=[LOCAL, CACHE]
2024-06-22T15:11:34.217+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : Started ExternalReadApplication in 0.387 seconds (process running for 0.578)
@PostConstruct 애노테이션으로 등록된 메서드가 실행되어 값이 잘 출력되는것을 볼 수 있다.
이 @ConfigurationProperties는 타입 안전 외부 설정이다. 즉, 아래와 같이 등록한 필드들의 타입을 보면
private String url;
private String username;
private String password;
private Etc etc;
이 타입이 아닌 값이 외부 설정으로 부터 들어오면 에러를 뱉어낸다. 또한 계층 구조도 일치하는지 확인해주기 때문에 안전하고 재사용 가능한 객체 형태의 외부 설정값을 가져올 수 있다.
자, 객체 형태로 외부 설정을 가져와 빈으로 등록해서 여기저기 주입을 통해 사용할 수 있다는 것도 알게됐다. 근데 한가지 불편한 점이 있는데 아래 @ConfigurationProperties("my.datasource") 애노테이션을 붙였는데,
@Data
@ConfigurationProperties("my.datasource")
public class MyDataSourcePropertiesV1 {...}
여기서 또 @EnableConfigurationProperties(MyDataSourcePropertiesV1.class) 애노테이션을 붙여야 한다는 점이다.
@Slf4j
@EnableConfigurationProperties(MyDataSourcePropertiesV1.class)
public class MyDataSourcePropertiesConfigV1 {...}
그냥 한번만 애노테이션을 달면 좋겠는데, 귀찮게 두번 다 해줘야한다. 이 또한 해결 방법이 있다. 아래 애노테이션을 스프링 부트의 메인 클래스에 붙여주면 메인 클래스부터 하위 모든 패키지를 찾아서 @ConfigurationProperties 애노테이션을 등록한 클래스를 빈으로 알아서 등록해준다.
@ConfigurationPropertiesScan
확인해보자. 아래는 스프링 부트의 메인 클래스이다.
package hello;
import hello.config.MyDataSourceEnvConfig;
import hello.config.MyDataSourcePropertiesConfigV1;
import hello.config.MyDataSourceValueConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.Import;
//@Import(MyDataSourceEnvConfig.class)
//@Import(MyDataSourceValueConfig.class)
@Import(MyDataSourcePropertiesConfigV1.class)
@ConfigurationPropertiesScan
@SpringBootApplication(scanBasePackages = "hello.datasource")
public class ExternalReadApplication {
public static void main(String[] args) {
SpringApplication.run(ExternalReadApplication.class, args);
}
}
MyDataSourcePropertiesConfigV1
package hello.config;
import hello.datasource.MyDataSource;
import hello.datasource.MyDataSourcePropertiesV1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@Slf4j
// @EnableConfigurationProperties(MyDataSourcePropertiesV1.class)
public class MyDataSourcePropertiesConfigV1 {
private final MyDataSourcePropertiesV1 properties;
public MyDataSourcePropertiesConfigV1(MyDataSourcePropertiesV1 properties) {
this.properties = properties;
}
@Bean
public MyDataSource dataSource() {
return new MyDataSource(
properties.getUrl(),
properties.getUsername(),
properties.getPassword(),
properties.getEtc().getMaxConnection(),
properties.getEtc().getTimeout(),
properties.getEtc().getOptions());
}
}
그리고 이제 @EnableConfigurationProperties(MyDataSourcePropertiesV1.class) 이 애노테이션을 주석처리했다.
실행해보면 결과는 동일하게 잘 동작한다.
실행결과
2024-06-22T15:11:34.007+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : Starting ExternalReadApplication using Java 17.0.9 with PID 1827 (/Users/choichiwon/Spring/external-read/out/production/classes started by choichiwon in /Users/choichiwon/Spring/external-read)
2024-06-22T15:11:34.008+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : No active profile set, falling back to 1 default profile: "default"
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : url=local.db.com
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : username=local_user
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : password=local_pw
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : maxConnection=1
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : timeout=PT1M
2024-06-22T15:11:34.179+09:00 INFO 1827 --- [ main] hello.datasource.MyDataSource : options=[LOCAL, CACHE]
2024-06-22T15:11:34.217+09:00 INFO 1827 --- [ main] hello.ExternalReadApplication : Started ExternalReadApplication in 0.387 seconds (process running for 0.578)
남은 문제
어느 정도 해결된 것 같지만, 한가지 정말 불편한 점이 있다. Lombok의 @Data 애노테이션을 사용했는데 이 애노테이션은 Setter를 자동으로 만들어주는 것이다. Setter는 되도록이면 없어야 한다. 적어도 난 그렇게한다. 세터로부터 파생되는 찾기 힘든 문제들이 너무 많기 때문에. 그래서 이 Setter 대신 생성자를 통해서 외부 설정 값을 넣는 방법을 알아보자.
외부 설정 사용 - @ConfigurationProperties (생성자를 통해서)
위에 말한것처럼, 남은 문제가 있다. Setter를 남겨두고 싶지 않다. 그래서 생성자를 통해 외부 설정 값을 주입하는 방법이 있다.
아주 간단한데, 생성자만 만들면 끝이다.
MyDataSourcePropertiesV2
package hello.datasource;
import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@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;
public Etc(int maxConnection,
Duration timeout,
@DefaultValue("DEFAULT") List<String> options) {
this.maxConnection = maxConnection;
this.timeout = timeout;
this.options = options;
}
}
}
우선 V2를 만든다. 여기서는 @Data를 지우고, @Getter만 남겨두자. 그리고 이 클래스의 생성자를 만들면 된다. 위 코드처럼. 그럼 끝이다.
실행결과
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : url=local.db.com
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : username=local_user
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : password=local_pw
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : maxConnection=1
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : timeout=PT1M
2024-06-29T15:22:08.257+09:00 INFO 71180 --- [ main] hello.datasource.MyDataSource : options=[DEFAULT]
2024-06-29T15:22:08.297+09:00 INFO 71180 --- [ main] hello.ExternalReadApplication : Started ExternalReadApplication in 0.397 seconds (process running for 0.589)
Process finished with exit code 0
@PostConstruct 애노테이션으로부터 실행되는 메서드의 로그가 잘 출력됐고, 값도 잘 들어갔다. 그리고 V2에 보면 내부 클래스(Etc)의 생성자에 보면 @DefaultValue라는 애노테이션이 있다. 이건 외부 설정으로부터 해당 키가 없으면 그 값에 기본값을 넣어주는 방법이다. 그래서 해당 키가 있으면 그 값을 그대로 가져오고 없으면 저기에 선언한 기본값을 넣어준다.
스프링 3.0 이전에는 생성자에 @ConstructorBinding 애노테이션이 없으면 안됐다. 필수적으로 달아줘야 했던 애노테이션인데, 3.0 이후에는 생성자가 하나뿐이라면 생략 가능하다. 그래서 위 코드에서도 해당 애노테이션은 없다.
남은 문제
남은 문제가 또 있다고?! 라고 생각하겠지만, 문제라기보단 더 많은 기능을 원한다. 이제는 생성자를 통해서 외부 설정값을 받아오고, 타입 안정성도 체크가 된다. 근데 검증을 하고 싶다. 예를 들면, max-connection이 최소 1보단 커야 이 값의 의미가 있다고 가정할때 0이 들어오면 아무런 의미없게 애플리케이션은 정상 동작을 하지 않을것이다. 그러나 타입 안정성에는 아무런 문제가 없기 때문에 어떤 에러로 인식시켜 주지 않는다. 내가 원하는건 만약 내가 실수로 0 또는 그보다 작은 수를 적었으면 바로 에러를 띄워 알려주길 원한다. 이게 가능할까?
외부 설정 사용 - @ConfigurationProperties (검증기 도입)
이제는 한 단계 더 나아가서 검증 기능까지 추가해서 더 안전한 외부 설정 주입을 사용해보자.
우선, 추가적인 의존성이 필요하다.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
위와 같이 의존성 하나를 더 추가해주자. 그러면 다음과 같이 두 개가 보이면 된다.
참고로, 위 두개 중 패키지 이름에 jakarta.validation으로 시작하는 것은 자바 표준 검증기에서 지원하는 기능이다. org.hibernate.validator로 시작하는 것은 자바 표준 검증기에서 아직 표준화 된 기능은 아니고 하이버네이트 검증기라는 표준 검증기의 구현체에서 직접 제공하는 기능이다. 대부분 하이버네이트 검증기를 사용하므로 크게 문제될 건 없다.
그리고 외부 설정을 객체로 받을 클래스 하나를 새로 만든다.
MyDataSourcePropertiesV3
package hello.datasource;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import org.hibernate.validator.constraints.time.DurationMax;
import org.hibernate.validator.constraints.time.DurationMin;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;
import java.time.Duration;
import java.util.List;
@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;
public Etc(int maxConnection,
Duration timeout,
@DefaultValue("DEFAULT") List<String> options) {
this.maxConnection = maxConnection;
this.timeout = timeout;
this.options = options;
}
}
}
중요한 애노테이션은 클래스 레벨에 붙어있는 @Validated 이다. 이 애노테이션이 있어야 검증을 수행한다.
그리고, 각 필드별로 원하는 검증 단계를 적용할 수 있다. 위 코드로 예를 들면, @NotEmpty는 빈 값이면 안된다는 검증 단계이다.
그리고 @Min(1), @Max(999)는 말 그대로 최소값은 1, 최대값은 999란 소리다.
이렇게 검증기를 추가해서 더 안전한 외부 설정을 사용할 수 있다.
실행해보자. 현재 상태는 검증기도 다 만족하는 상태이기 때문에 다음과 같이 잘 실행된다.
2024-06-30T15:56:26.642+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : url: local.db.com
2024-06-30T15:56:26.642+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : username: username
2024-06-30T15:56:26.643+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : password: password
2024-06-30T15:56:26.643+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : maxConnection: 1
2024-06-30T15:56:26.643+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : timeout: PT3.5S
2024-06-30T15:56:26.643+09:00 INFO 18860 --- [ main] hello.datasource.MyDataSource : options: [CACHE, ADMIN]
2024-06-30T15:56:26.790+09:00 INFO 18860 --- [ main] hello.ExternalReadApplication : Started ExternalReadApplication in 0.744 seconds (process running for 1.084)
Process finished with exit code 0
그런데, 만약 내가 max-connection 값을 다음과 같이 0으로 바꾼다고 하면,
my:
datasource:
url: local.db.com
username: username
password: password
etc:
max-connection: 0 # 이 부분!
timeout: 3500ms
options: CACHE,ADMIN
실행 시 이러한 에러가 나타난다.
결론
이렇게 검증까지도 구현해 보았다. 외부 설정을 사용하고 읽어들이는 방법도 잘 사용해서 좋은 애플리케이션을 만들어보자!
'Spring, Apache, Java' 카테고리의 다른 글
[프로덕션 준비] 모니터링 Part.1 Actuator 사용하기 (0) | 2024.06.30 |
---|---|
로컬 환경과 운영 환경에 구분될 빈 등록하는 방법 (0) | 2024.06.30 |
외부 설정과 프로필 관리 Part.2 (0) | 2024.06.14 |
외부 설정과 프로필 관리 Part.1 (0) | 2024.06.14 |
라이브러리 직접 만들고 다른 프로젝트에 자동 구성으로 적용해보기 (8) | 2024.06.13 |