인프런에서 백기선님의 스프링부트 개념과 활용 강의를 듣고, 개인적으로 공부하며 핵심만 정리한 글입니다.
외부 설정 사용하기
Properties
resources
디렉토리 안에 있는 application.properties
파일에 키 = 값 형태로 일종의 설정 값들을 따로 구분하여 저장해놓을 수 있다.
이를 코드에서는 @Value("${key}")
로 가져올 수 있다.
예를 들면 다음과 같다.
// application.properties
heumsi.name = heumsi
// SampleRunner.java
@Value("${heumsi.name}")
private String name; // name 에 heumsi 가 바인딩 됨.
...
Environment
Environment
객체를 가져와 .getProperty("key")
메쏘드로 설정 값을 가져올 수 있다.
@Autowired
Environment environment;
private String name = environment.getProperty("heumsi.name");
// name 에 heumsi 가 바인딩 됨.
...
테스트에서의 외부 설정
테스트를 실행 하면, main -> test 순으로 프로젝트를 빌딩하고,
test 에 있는 파일들이 main 에 있는 파일들을 오버라이딩함.
즉, main 과 test 에 동일하게 application.properties
가 있다면, test 내의 application.properties
가 최종적으로 사용됨.
따라서, 테스트 환경에서 main 과 다르게 별도의 설정을 주어야 하는 경우 주의가 필요함.
이를 위해 테스트 파일에서 외부 설정을 다르게 주는 방법은 다음과 같이 있음.
1) @SpringBootTest
의 Properties 속성
// SpringinitApplicationTest.java
@RunWith(SpringRunner.class)
@SpringBootTest(properties = "heumsi.name = heumsiTest")
public class SpringinitApplicationTest {
@Autowired
Environment environment
@Test
public void contextLoads {
String name = environment.getProperty("heumsi.name");
// name 에 위에서 변경한 heumsiTest 가 바인딩 됨.
}
}
2) @TestPropertySource
사용
// SpringinitApplicationTest.java
@RunWith(SpringRunner.class)
@TestPropertySource(properties = {"heumsi.name = heumsiTest", })
@SpringBootTest
public class SpringinitApplicationTest {
...
}
혹은 별도의 설정파일 test/resources/test.properties
을 만들어 놓고, 다음과 같이 사용 가능하다.
// SpringinitApplicationTest.java
@RunWith(SpringRunner.class)
@TestPropertySource(locations = "classpath:/test.properties")
@SpringBootTest
public class SpringinitApplicationTest {
...
}
우선 순위
불러오는 설정 값은 여러 곳에서 오버라이딩될 수 있기 때문에, 누가 누구를 오버라이딩하는지 우선순위를 알아야 한다.
1) Property 우선 순위
우선 순위를 간략히 정리하면 다음과 같다.
@TestPropertySource
@SpringBootTest(properties=...)
- 커맨드 라인 argument
@PropertySource
- 기본 프로퍼티
2) Properties 파일 우선순위
application.properties
는 resources/
말고 다른 곳에서도 사용될 수 있다.
이 때 application.properties
의 위치에 따른 우선 순위는 다음과 같다.
/config/
/
<classpath>/config/
<classpath>/
플레이스 홀더와 랜덤 값
application.properties
에서 다음과 같이 사용 가능하다.
// application.properties
// place holder (재 사용 가능)
heumsi.lastName = Jeon
heumsi.firstName = heumsi
heumsi.name = ${heumsi.lastName} ${heumsi.firstname}
// random number (랜덤 값 입력하기)
random.number = ${random.int}
외부 설정 Bean 으로 만들기
외부 설정 파일을 하나의 클래스로 만들어, 이를 코드 내부에서 Bean 으로 등록한 뒤 사용할 수 있다.
먼저 applcation.properties
는 다음과 같이 입력되있다고 하자.
// application.properties
heumsi.firstName = heumsi
heumsi.lastName = jeon
heumsi.age = ${random.int(0,100)}
heumsi.fullName = ${heumsi.firstName} ${heumsi.lastName}
여기서 heumsi.
에 해당하는 설정 값들만 고려하여 클래스로 정의하자.
// HeumsiProperties.java
@Component // 빈 등록
@ConfigurationProperties("heumsi") // application.properties 와 바인딩
public class HeumsiProperties {
String firstName;
String lastName;
int age;
String fullName;
... (getter, setter)
Bean 으로 등록되었으니, 이제 @Autowired
로 주입받아 접근하는게 가능해진다.
예를 들어 다음과 같이 사용할 수 있다.
// SampleRunner.java
@Component
public class SampleRunner implements ApplicationRunner {
@Autowired
HeumsiProperties heumsiProperties;
@Override
public void run(ApplicationArguments args) throws Exception {
String fullName = heumsiProperties.getFullName();
int age = heumsiProperties.getAge();
}
}
application.property
더 알아보기
1) 융통성 있는(Relaxed) 바인딩
application.properties
는 키 이름에 _ (under score)
나 - (kebab)
가 포함되어도 알아서 camleCase
로 변환하여 바인딩 한다.
heumsi.full-name
heumsi.full_name
위 모두 heumsi.fullName 에 바인딩 됨.
2) Duration Type 컨버전
application.properties
안에 있는 키, 값들은 사실 모두 문자열 형태로 존재하지만, Bean 으로 등록되는 클래스와 바인딩될 때, String
, int
, Duration
등으로 모두 타입 컨버전 된다. (이는 스프링이 제공하는 기능)
특히 Duration
의 예시를 좀 더 살펴보면
// HeumsiProperties.java
@Component
@ConfigurationProperties("heumsi")
public class HeumsiProperties {
...
private Duration sessionTimeout = Duration.ofSeconds(30);
// 기본 값 30초
}
// application.properties
heumsi.sessionTimeout = 20s
위와 같이 s
, m
, d
등과 같은 suffix 로 Duration
타입임을 명시하고 바인딩시켜줄 수 있다.
3) Validate 로 값 검증
다음과 같이 @Validated
와 @NotEmpty
가 추가되었다고 생각해보자.
// HeumsiProperties.java
@Component
@ConfigurationProperties("heumsi")
@Validated
public class HeumsiProperties {
@NotEmpty
private String name
}
그리고 application.properties
에서 heumsi.name
으로 다음과 같이 빈 값을 주면
컴파일 과정 중 에러를 발생시킨다.
// application.properties
heumsi.name =
...
@NotEmpty
외에도 다양한 어노테이션이 있는데, 이는 JSR-303 을 참고하면 된다.
'더 나은 엔지니어가 되기 위해 > 지금은 안쓰는 자바' 카테고리의 다른 글
[스프링 부트 개념과 활용] 로깅 (0) | 2020.02.03 |
---|---|
[스프링 부트 개념과 활용] Profile (0) | 2020.02.03 |
[스프링 부트 개념과 활용] SpringApplication (0) | 2020.01.31 |
[스프링 부트 개념과 활용] 내장 웹서버 이해와 .JAR 생성 (0) | 2020.01.31 |
[스프링 부트 개념과 활용] 의존성 관리, 자동 설정 이해 (0) | 2020.01.30 |