1. 개요
이 예제에서는 Java 구성 및 @PropertySource 를 통해 Spring에서 속성을 설정하고 사용하는 방법을 보여 줍니다 .
또한 Spring Boot에서 속성이 작동하는 방식도 살펴보겠습니다.
2. 어노테이션을 통해 속성 파일 등록
Spring 3.1은 또한 환경에 속성 소스를 추가하기 위한 편리한 메커니즘으로 새로운 @PropertySource 어노테이션 을 도입 합니다.
@Configuration 어노테이션 과 함께 이 어노테이션을 사용할 수 있습니다 .
@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
//...
}
새 속성 파일을 등록하는 또 다른 매우 유용한 방법은 자리 표시자를 사용하여 런타임에 올바른 파일 을 동적으로 선택할 수 있도록 하는 것입니다 .
@PropertySource({
"classpath:persistence-${envTarget:mysql}.properties"
})
...
2.1. 여러 속성 위치 정의
@PropertySource의 어노테이션 반복입니다 자바 8 규칙에 따라 . 따라서 Java 8 이상을 사용하는 경우 이 어노테이션을 사용하여 여러 속성 위치를 정의할 수 있습니다.
@PropertySource("classpath:foo.properties")
@PropertySource("classpath:bar.properties")
public class PropertiesWithJavaConfig {
//...
}
물론, 우리는 또한 사용할 수 있습니다 @PropertySources의 어노테이션과의 배열을 지정 @PropertySource을 . 이것은 Java 8 이상뿐만 아니라 지원되는 모든 Java 버전에서 작동합니다.
@PropertySources({
@PropertySource("classpath:foo.properties"),
@PropertySource("classpath:bar.properties")
})
public class PropertiesWithJavaConfig {
//...
}
두 경우 모두 속성 이름 충돌이 발생하는 경우 마지막 소스 읽기가 우선한다는 점에 유의해야 합니다.
3. 속성 사용/주입
@Value 어노테이션 으로 속성을 주입하는 것은 간단합니다.
@Value( "${jdbc.url}" )
private String jdbcUrl;
속성의 기본값을 지정할 수도 있습니다.
@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;
Spring 3.1에 추가된 새로운 PropertySourcesPlaceholderConfigurer 는 빈 정의 속성 값과 @Value 어노테이션 내의 ${…} 자리 표시자를 해결 합니다.
마지막으로 Environment API를 사용하여 속성 값을 얻을 수 있습니다 .
@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));
4. 스프링 부트 속성
속성에 대한 고급 구성 옵션을 살펴보기 전에 Spring Boot에서 지원하는 새 속성을 살펴보겠습니다.
일반적으로 이 새로운 지원은 표준 Spring에 비해 구성이 덜 포함 되며 이는 물론 Boot의 주요 목표 중 하나입니다.
4.1. application.properties: 기본 속성 파일
부팅은 속성 파일에 대한 구성 접근 방식보다 일반적인 규칙을 적용합니다. 즉, src/main/resources 디렉토리 에 application.properties 파일을 넣으면 자동으로 감지 됩니다. 그런 다음 정상적으로 로드된 속성을 주입할 수 있습니다.
따라서 이 기본 파일을 사용하면 PropertySource 를 명시적으로 등록 하거나 속성 파일에 대한 경로를 제공 할 필요가 없습니다 .
필요한 경우 환경 속성을 사용하여 런타임에 다른 파일을 구성할 수도 있습니다.
java -jar app.jar --spring.config.location=classpath:/another-location.properties
현재 Spring 부팅 2.3 , 우리는 또한 구성 파일에 대한 와일드 카드 위치를 지정할 수 있습니다 .
예를 들어 spring.config.location 속성을 config/*/ 로 설정할 수 있습니다 .
java -jar app.jar --spring.config.location=config/*/
이런 식으로 Spring Boot는 jar 파일 외부 에서 config/*/ 디렉토리 패턴과 일치하는 구성 파일을 찾습니다 . 이는 구성 속성의 소스가 여러 개인 경우에 유용합니다.
버전 2.4.0 부터 Spring Boot는 YAML이 의도적으로 수행 하는 것과 유사하게 다중 문서 속성 파일 사용을 지원합니다 .
baeldung.customProperty=defaultValue
#---
baeldung.customProperty=overriddenValue
속성 파일의 경우 세 개의 대시 표기법 앞에 어노테이션 문자( # ) 가 옵니다 .
4.2. 환경별 속성 파일
다른 환경을 대상으로 해야 하는 경우 Boot에 이에 대한 기본 제공 메커니즘이 있습니다.
src/main/resources 디렉토리 에 application-environment.properties 파일을 정의 하고 동일한 환경 이름으로 Spring 프로필을 설정할 수 있습니다.
예를 들어 "staging" 환경을 정의하면 staging 프로필 을 정의한 다음 application-staging.properties 를 정의해야 합니다 .
이 env 파일이 로드되고 기본 속성 파일보다 우선합니다. 기본 파일은 계속 로드되며 속성 충돌이 있을 때 환경별 속성 파일이 우선한다는 점에 유의하세요.
4.3. 테스트별 속성 파일
애플리케이션이 테스트 중일 때 다른 속성 값을 사용해야 하는 요구 사항이 있을 수도 있습니다.
Spring Boot는 테스트 실행 중에 src/test/resources 디렉토리 를 살펴Spring으로써 이를 처리 합니다 . 다시 말하지만, 기본 속성은 여전히 정상적으로 주입 가능하지만 충돌이 있는 경우 이러한 속성에 의해 재정의됩니다.
4.4. @TestPropertySource 어노테이션
테스트 속성에 대해 더 세분화된 제어가 필요한 경우 @TestPropertySource 어노테이션을 사용할 수 있습니다 .
이를 통해 기본 속성 소스보다 우선적으로 특정 테스트 컨텍스트에 대한 테스트 속성을 설정할 수 있습니다.
@RunWith(SpringRunner.class)
@TestPropertySource("/foo.properties")
public class FilePropertyInjectionUnitTest {
@Value("${foo}")
private String foo;
@Test
public void whenFilePropertyProvided_thenProperlyInjected() {
assertThat(foo).isEqualTo("bar");
}
}
파일을 사용하지 않으려면 이름과 값을 직접 지정할 수 있습니다.
@RunWith(SpringRunner.class)
@TestPropertySource(properties = {"foo=bar"})
public class PropertyInjectionUnitTest {
@Value("${foo}")
private String foo;
@Test
public void whenPropertyProvided_thenProperlyInjected() {
assertThat(foo).isEqualTo("bar");
}
}
@SpringBootTest 어노테이션 의 속성 인수를 사용하여 유사한 효과를 얻을 수도 있습니다 .
@RunWith(SpringRunner.class)
@SpringBootTest(
properties = {"foo=bar"}, classes = SpringBootPropertiesTestApplication.class)
public class SpringBootPropertyInjectionIntegrationTest {
@Value("${foo}")
private String foo;
@Test
public void whenSpringBootPropertyProvided_thenProperlyInjected() {
assertThat(foo).isEqualTo("bar");
}
}
4.5. 계층적 속성
함께 그룹화된 속성이 있는 경우 @ConfigurationProperties 어노테이션 을 사용할 수 있습니다. 이 어노테이션은 이러한 속성 계층을 Java 개체 그래프에 매핑합니다.
데이터베이스 연결을 구성하는 데 사용되는 몇 가지 속성을 살펴보겠습니다.
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
그런 다음 어노테이션을 사용하여 데이터베이스 개체에 매핑해 보겠습니다.
@ConfigurationProperties(prefix = "database")
public class Database {
String url;
String username;
String password;
// standard getters and setters
}
Spring Boot는 속성 이름과 해당 필드 사이를 자동으로 매핑하여 구성 접근 방식보다 규칙을 다시 적용합니다. 우리가 제공해야 하는 것은 속성 접두사입니다.
구성 속성에 대해 더 자세히 알아보려면 심층 기사 를 참조하십시오 .
4.6. 대안: YAML 파일
Spring은 YAML 파일도 지원합니다.
테스트별, 환경별 및 기본 속성 파일에 모두 동일한 이름 지정 규칙이 적용됩니다. 유일한 차이점은 파일 확장자와 클래스 경로 에 있는 SnakeYAML 라이브러리 에 대한 의존성입니다 .
YAML은 계층적 속성 저장에 특히 좋습니다 . 다음 속성 파일:
database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo
다음 YAML 파일과 동의어입니다.
database:
url: jdbc:postgresql:/localhost:5432/instance
username: foo
password: bar
secret: foo
YAML 파일은 @PropertySource 어노테이션을 지원하지 않으므로 이 어노테이션을 사용해야 하는 경우 속성 파일을 사용하도록 제한 된다는 점도 언급할 가치가 있습니다.
또 다른 주목할만한 점은 버전 2.4.0에서 Spring Boot가 다중 문서 YAML 파일에서 속성이 로드되는 방식을 변경했다는 것입니다. 이전에는 추가된 순서가 프로필 활성화 순서를 기반으로 했습니다. 그러나 새 버전에서 프레임워크는 이전에 .properties 파일에 대해 표시한 것과 동일한 순서 지정 규칙을 따릅니다 . 파일에서 더 낮게 선언된 속성은 단순히 상위 속성을 재정의합니다.
또한 이 버전에서는 더 이상 프로필 관련 문서에서 프로필을 활성화할 수 없으므로 결과가 더 명확하고 예측 가능합니다.
4.7. 추가 구성 파일 가져오기
버전 2.4.0 이전에는 Spring Boot에서 spring.config.location 및 spring.config.additional-location 속성을 사용하여 추가 구성 파일을 포함 할 수 있었지만 특정 제한 사항이 있었습니다. 예를 들어 프로세스 초기에 사용되었기 때문에 애플리케이션을 시작하기 전에(환경 또는 시스템 속성으로 또는 명령줄 인수를 사용하여) 정의해야 했습니다.
언급된 버전에서는 application.properties 또는 application.yml 파일 내의 spring.config.import 속성을 사용하여 추가 파일을 쉽게 포함할 수 있습니다. 이 속성은 몇 가지 흥미로운 기능을 지원합니다.
- 여러 파일 또는 디렉토리 추가
- 파일은 클래스 경로 또는 외부 디렉토리에서 로드할 수 있습니다.
- 파일을 찾을 수 없는 경우 또는 선택적 파일인 경우 시작 프로세스가 실패해야 하는지 여부를 나타냅니다.
- 확장자가 없는 파일 가져오기
유효한 예를 살펴보겠습니다.
spring.config.import=classpath:additional-application.properties,
classpath:additional-application[.yml],
optional:file:./external.properties,
classpath:additional-application-properties/
참고: 여기서는 명확성을 위해 줄 바꿈을 사용하여 이 속성의 형식을 지정했습니다.
Spring은 import를 import 선언 바로 아래에 삽입된 새 문서로 취급할 것입니다.
4.8. 명령줄 인수의 속성
파일을 사용하는 것 외에도 명령줄에서 직접 속성을 전달할 수 있습니다.
java -jar app.jar --property="value"
-jar 명령 이후가 아니라 이전에 제공되는 시스템 속성을 통해 이 작업을 수행할 수도 있습니다.
java -Dproperty.name="value" -jar app.jar
4.9. 환경 변수의 속성
Spring Boot는 환경 변수도 감지하여 속성으로 처리합니다.
export name=value
java -jar app.jar
4.10. 속성 값의 무작위화
결정적인 속성 값을 원하지 않으면 RandomValuePropertySource 를 사용하여 속성 값 을 무작위로 지정할 수 있습니다 .
random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}
4.11. 추가 유형의 속성 소스
Spring Boot는 합리적인 재정의를 허용하기 위해 신중한 순서를 구현하여 다양한 속성 소스를 지원합니다. 이 문서의 범위를 넘어서는 공식 문서를 참조할 가치가 있습니다.
5. 원시 빈을 사용한 설정 — PropertySourcesPlaceholderConfigurer
속성을 Spring으로 가져오는 편리한 방법 외에도 속성 구성 빈을 수동으로 정의하고 등록할 수도 있습니다.
PropertySourcesPlaceholderConfigurer로 작업 하면 더 장황하고 대부분의 경우 불필요하다는 단점이 있지만 구성을 완전히 제어할 수 있습니다.
Java 구성을 사용하여 이 빈을 정의하는 방법을 살펴보겠습니다.
@Bean
public static PropertySourcesPlaceholderConfigurer properties(){
PropertySourcesPlaceholderConfigurer pspc
= new PropertySourcesPlaceholderConfigurer();
Resource[] resources = new ClassPathResource[ ]
{ new ClassPathResource( "foo.properties" ) };
pspc.setLocations( resources );
pspc.setIgnoreUnresolvablePlaceholders( true );
return pspc;
}
6. 부모-자식 컨텍스트의 속성
이 질문이 계속해서 나옵니다. 웹 애플리케이션에 부모 컨텍스트와 자식 컨텍스트 가 있으면 어떻게 됩니까 ? 상위 컨텍스트에는 몇 가지 공통 핵심 기능과 빈이 있을 수 있으며, 서블릿별 빈을 포함할 수 있는 하나(또는 여러 개의) 하위 컨텍스트가 있을 수 있습니다.
이 경우 속성 파일을 정의하고 이러한 컨텍스트에 포함하는 가장 좋은 방법은 무엇입니까? 그리고 Spring에서 이러한 속성을 가장 잘 검색하는 방법은 무엇입니까?
간단하게 정리해드리겠습니다.
파일이 상위 컨텍스트에 정의된 경우 :
- @Value 는 하위 컨텍스트 에서 작동합니다 : 예
- @Value 는 부모 컨텍스트 에서 작동합니다 : 예
- environment.getProperty 에서 하위 컨텍스트 : YES
- environment.getProperty 의 상위 컨텍스트 : YES
파일이 하위 컨텍스트에 정의된 경우 :
- @Value 는 하위 컨텍스트 에서 작동합니다 : 예
- @Value 는 상위 컨텍스트 에서 작동합니다 . NO
- environment.getProperty 에서 하위 컨텍스트 : YES
- environment.getProperty 에서 부모 컨텍스트 : NO
7. 결론
이 기사에서는 Spring에서 속성 및 속성 파일로 작업하는 몇 가지 예를 보여주었습니다.