Spring Boot 및 여러 외부 구성 파일


125

클래스 경로에서로드하려는 여러 속성 파일이 있습니다. 의 /src/main/resources일부인 기본 세트가 하나 있습니다 myapp.jar. 내 springcontext파일이 클래스 경로에있을 것으로 예상합니다. 즉

<util:properties id="Job1Props"
    location="classpath:job1.properties"></util:properties>

<util:properties id="Job2Props"
    location="classpath:job2.properties"></util:properties>

또한 이러한 속성을 외부 집합으로 재정의하는 옵션이 필요합니다. 에 외부 구성 폴더가 cwd있습니다. 스프링 부트 문서 구성 폴더에 따라 클래스 경로에 있어야합니다. 그러나 applicaiton.properties거기에서 또는 config의 모든 속성을 재정의하는 경우 문서에서 명확하지 않습니다 .

내가 그것을 테스트했을 때만 application.properties선택되고 나머지 속성은 여전히 /src/main/resources. 쉼표로 구분 된 목록으로 제공하려고 시도 spring.config.location했지만 기본 집합은 여전히 ​​재정의되지 않습니다.

여러 외부 구성 파일이 기본 구성 파일을 무시하도록하려면 어떻게해야합니까?

해결 방법으로 현재 app.config.location명령 줄을 통해 제공하는 (앱 특정 속성)을 사용했습니다 . 즉

java -jar myapp.jar app.config.location=file:./config

그리고 나는 나의 변화 applicationcontext에를

<util:properties id="Job2Props"
    location="{app.config.location}/job2.properties"></util:properties>

그리고 이것이 Application을로드하는 동안 파일과 클래스 경로를 분리하는 방법입니다.
편집 :

//psuedo code

if (StringUtils.isBlank(app.config.location)) {
            System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}

위의 해결 방법을 사용하지 않고 파일과 마찬가지로 클래스 경로의 모든 외부 구성 파일을 봄이 재정의하도록하고 싶습니다 application.properties.


4
application.properties항상,로드됩니다 spring.config.location당신이 파일을 체크 추가 구성 위치를 추가 할 수 있습니다 (그것으로 끝나는 경우 즉 /당신이 그이로드 될 파일이있는 점에 쉼표로 분리 된 목록을 넣어 그러나 경우). 이것은 Spring Boot Reference Guide에도 설명되어 있습니다
M. Deinum

답변:


155

Spring Boot를 사용할 때 속성은 다음 순서로로드됩니다 ( Spring Boot 참조 가이드의 Externalized Configuration 참조).

  1. 명령 줄 인수.
  2. 자바 시스템 속성 (System.getProperties ()).
  3. OS 환경 변수.
  4. java : comp / env의 JNDI 속성
  5. random. *에 속성 만있는 RandomValuePropertySource입니다.
  6. 패키지 된 jar 외부의 애플리케이션 속성 (YAML 및 프로필 변형을 포함한 application.properties)
  7. jar 내부에 패키징 된 애플리케이션 속성 (YAML 및 프로필 변형을 포함한 application.properties).
  8. @Configuration 클래스의 @PropertySource 주석.
  9. 기본 속성 (SpringApplication.setDefaultProperties를 사용하여 지정됨).

속성을 확인할 때 (즉, @Value("${myprop}")확인은 역순으로 수행됩니다 (따라서 9로 시작).

다른 파일을 추가하려면 spring.config.location쉼표로 구분 된 속성 파일 목록 또는 파일 위치 (디렉터리)를 사용하는 속성을 사용할 수 있습니다 .

-Dspring.config.location=your/config/dir/

위의 application.properties파일 은 파일을 참조 할 디렉토리를 추가 합니다.

-Dspring.config.location=classpath:job1.properties,classpath:job2.properties

로드 된 파일에 2 개의 속성 파일이 추가됩니다.

기본 구성 파일 및 위치는 추가로 지정된 spring.config.location항목 보다 먼저로드 됩니다. 즉, 후자는 항상 이전 항목에 설정된 속성을 재정의합니다. ( Spring Boot Reference Guide 의이 섹션 도 참조하십시오 ).

spring.config.location디렉토리 (파일과 반대)가 포함 된 경우 /로 끝나야합니다 ( spring.config.name로드되기 전에 생성 된 이름이 추가됩니다 ). 의 classpath:,classpath:/config,file:,file:config/값에 관계없이 기본 검색 경로 가 항상 사용됩니다 spring.config.location. 이러한 방식으로 애플리케이션의 기본값을에서 application.properties(또는으로 선택한 다른 기본 이름 spring.config.name) 설정하고 런타임에 기본값을 유지하면서 다른 파일로 재정의 할 수 있습니다 .

업데이트 : spring.config.location의 동작이 이제 기본값을 추가하는 대신 재정의합니다. 기본값을 유지하려면 spring.config.additional-location을 사용해야합니다. 이것은 1.x에서 2.x 로의 동작 변경입니다.


2
감사합니다.하지만이 참조 문서를 이미 읽었으며 다음은 "-Dspring.config.location = your / config / dir / 위의 내용은 application.properties 파일에 대해 참조 할 디렉토리를 추가합니다." application.properties 파일은 무엇을 의미합니까? 그것은 하나의 파일입니다. 어쨌든 끝에 "/"가있는 전체 디렉토리를 선택할 수 있다면 각각을 쉼표로 구분 된 목록으로 지정할 필요가 없습니다. 나는 내 게시물에서 언급하지만 난 그것을주지 나는 두 접근 방식을 시도했다 생각 한 번 더 시도
NIR

문서에 명시된대로 application.properties및에 대한 다른 기본 위치처럼 선택합니다 application-[env].properties. 다른 속성 파일은 고려하지 않습니다. 이는 참조 가이드에도 명시되어 있습니다 (링크로 연결되는 섹션 및 참조 가이드의 인용문).
M. Deinum 2014 년

1
네,하지만 그것은 나에게 이해가되지 않는 것입니다. 그것은 당신이 좋은 imo가 아닌 하나의 속성 파일만을 사용하도록 강요합니다. tomcat에서와 같이 특정 디렉토리 (및 그 안에있는 모든 것)를 classpath에 넣도록 common.loader를 구성 할 수 있습니다. 왜 classloader가 부팅 할 수 없는지 지원할 수 있습니다.
nir

3
인용 문서는 도움이되지 않습니다. 문서가 명확하다면 (충분합니까? 특히 필요한 방식으로?) 질문은 필요하지 않습니다. 예를 들어,이 경우, 어떻게 정말 분명하지 않다 config.locationconfig.names아마 그들이 어떻게 상호 작용 이미 알고있는 사람들에게 취소 나타나지만, 상호 작용. 문서에 내용 을 추가 하기 위해 답변을 업데이트 할 수 있습니까 ?
Narfanator

13
spring.config.location이제 의 동작이 기본값을 추가하는 대신 재정의 하므로 업데이트해야 합니다. spring.config.additional-location기본값을 유지 하려면을 사용해야 합니다. 이것은 1.x에서 2.x 로의 동작 변경입니다.
Robin

32

Spring boot를 사용하면 spring.config.location이 작동하며 쉼표로 구분 된 속성 파일 만 제공합니다.

아래 코드를 참조하십시오

@PropertySource(ignoreResourceNotFound=true,value="classpath:jdbc-${spring.profiles.active}.properties")
public class DBConfig{

     @Value("${jdbc.host}")
        private String jdbcHostName;
     }
}

응용 프로그램에 jdbc.properties의 기본 버전을 넣을 수 있습니다. 외부 버전은 이것으로 설정할 수 있습니다.

java -jar target/myapp.jar --spring.config.location=classpath:file:///C:/Apps/springtest/jdbc.properties,classpath:file:///C:/Apps/springtest/jdbc-dev.properties

spring.profiles.active 속성을 사용하여 설정 한 프로필 값에 따라 jdbc.host 값이 선택됩니다. 그래서 언제 (윈도우에서)

set spring.profiles.active=dev

jdbc.host는 jdbc-dev.properties에서 값을 가져옵니다.

...에 대한

set spring.profiles.active=default

jdbc.host는 jdbc.properties에서 값을 가져옵니다.


첫 번째 코드 블록이 작동 할 것이라고 생각하지 않습니다. 나는 이것에 대해 스스로를 스터 빙 하고이 대답을 따랐습니다 . 적절한 설명에 대한 답변에서 참조 된 jira.springsource.org/browse/SPR-8539를 참조 하십시오 .
Sowka

27

Spring Boot 1.X 및 Spring Boot 2.X는 Externalized Configuration.

M. Deinum의 좋은 대답은 Spring Boot 1 사양을 나타냅니다.
여기서 Spring Boot 2를 업데이트하겠습니다.

환경 속성 소스 및 순서

Spring Boot 2는 PropertySource합리적인 값 재정의를 허용하도록 설계된 매우 특별한 순서를 사용합니다. 속성은 다음 순서로 고려됩니다.

  • 홈 디렉토리의 Devtools 전역 설정 속성 (devtools가 활성화 된 경우 ~ / .spring-boot-devtools.properties).

  • @TestPropertySource 테스트에 대한 주석.

  • @SpringBootTest#properties테스트의 주석 속성. 명령 줄 인수.

  • 속성 SPRING_APPLICATION_JSON(환경 변수 또는 시스템 속성에 포함 된 인라인 JSON).

  • ServletConfig 초기화 매개 변수.

  • ServletContext 초기화 매개 변수.

  • JNDI는에서 속성 java:comp/env.

  • Java System 속성 ( System.getProperties()).

  • OS 환경 변수.

  • RandomValuePropertySource랜덤으로 만 속성이 있는 A. *.

  • 패키지 된 jar ( application-{profile}.properties및 YAML 변형) 외부의 프로필 별 애플리케이션 속성 .

  • jar ( application-{profile}.properties및 YAML 변형) 내에 패키징 된 프로필 별 애플리케이션 속성 .

  • 패키지 된 jar ( application.properties및 YAML 변형) 외부의 애플리케이션 속성 .

  • jar ( application.properties및 YAML 변형) 내에 패키지 된 애플리케이션 속성 .

  • @PropertySource@Configuration수업 에 대한 주석 . 기본 속성 (설정으로 지정됨 SpringApplication.setDefaultProperties).

외부 속성 파일을 지정하려면 이러한 옵션이 중요합니다.

  • 패키지 된 jar ( application-{profile}.properties및 YAML 변형) 외부의 프로필 별 애플리케이션 속성 .

  • 패키지 된 jar ( application.properties및 YAML 변형) 외부의 애플리케이션 속성 .

  • @PropertySource@Configuration수업 에 대한 주석 . 기본 속성 (설정으로 지정됨 SpringApplication.setDefaultProperties).

이 세 가지 옵션 중 하나만 사용하거나 요구 사항에 따라 조합 할 수 있습니다.
예를 들어 매우 간단한 경우에는 프로필 별 속성 만 사용하는 것으로 충분하지만 다른 경우에는 프로필 별 속성, 기본 속성 및 @PropertySource.

application.properties 파일의 기본 위치

에 대한 application.properties기본 봄로드 그들과 다음과 같은 순서로 이들의 환경에서 자신의 속성을 추가하여 파일 (및 변형) :

  • 현재 디렉토리의 / config 하위 디렉토리

  • 현재 디렉토리

  • 클래스 경로 / config 패키지

  • 클래스 경로 루트

더 높은 우선 순위는 말 그대로 :
classpath:/,classpath:/config/,file:./,file:./config/.

특정 이름을 가진 속성 파일을 사용하는 방법은 무엇입니까?

기본 위치가 항상 충분하지는 않습니다. 기본 파일 이름 ( application.properties) 과 같은 기본 위치 는 적합하지 않을 수 있습니다. 게다가 OP 질문에서와 같이 application.properties(및 변형) 이외의 여러 구성 파일을 지정해야 할 수도 있습니다 .
그래서 spring.config.name충분하지 않을 것입니다.

이 경우 spring.config.location환경 속성 (쉼표로 구분 된 디렉터리 위치 또는 파일 경로 목록)을 사용하여 명시 적 위치를 제공해야합니다 .
파일 이름 패턴에 대한 자유를 얻으려면 디렉토리 목록보다 파일 경로 목록을 선호하십시오.
예를 들어 다음과 같이하십시오.

java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

이 방법은 폴더를 지정하는 것보다 가장 장황하지만 구성 파일을 매우 세밀하게 지정하고 효과적으로 사용되는 속성을 명확하게 문서화하는 방법이기도합니다.

spring.config.location은 이제 기본 위치를 추가하는 대신 대체합니다.

Spring Boot 1에서 spring.config.location인수는 Spring 환경에서 지정된 위치를 추가합니다.
그러나 Spring Boot 2에서는 문서에spring.config.location 명시된대로 Spring 환경의 지정된 위치에서 Spring이 사용하는 기본 위치를 대체합니다 .

를 사용하여 사용자 지정 구성 위치를 구성 spring.config.location하면 기본 위치가 대체됩니다. 예를 들어,이 spring.config.location값으로 설정되어 classpath:/custom-config/, file:./custom-config/검색 순서는 다음이된다 :

  1. file:./custom-config/

  2. classpath:custom-config/

spring.config.location이제 모든 application.properties파일이 명시 적으로 지정되어야 하는지 확인하는 방법 입니다. 파일
을 패키징하지 않는 우버 JAR의 경우에는 application.properties다소 좋습니다.

spring.config.locationSpring Boot 2를 사용하는 동안 의 이전 동작을 유지하려면 문서에 명시된대로 위치 추가하는 spring.config.additional-location대신 새 속성을 사용할 수 있습니다 .spring.config.location

또는를 사용하여 사용자 지정 구성 위치를 구성 spring.config.additional-location하면 기본 위치와 함께 사용됩니다.


실제로

따라서 OP 질문에서와 같이 지정할 외부 속성 파일 2 개와 uber jar에 포함 된 속성 파일 1 개가 있다고 가정합니다.

지정한 구성 파일 만 사용하려면 다음을 수행하십시오.

-Dspring.config.location=classpath:/job1.properties,classpath:/job2.properties,classpath:/applications.properties   

기본 위치에 구성 파일을 추가하려면 다음을 수행하십시오.

-Dspring.config.additional-location=classpath:/job1.properties,classpath:/job2.properties

classpath:/applications.properties 마지막 예에서는 기본 위치에 필요하지 않으며 기본 위치는 여기에서 덮어 쓰지 않고 확장됩니다.


당신의 대답은 한 가지를 제외하고는 정말 완전하다 : "classpath : /job1.properties"를 지정하면 Spring은 디스크에서 외부 구성 job1.properties를 어디에서 찾을 것인가? 여기에서 클래스 경로에 외부 속성을 포함하는 디렉토리를 어떻게 추가 했습니까?
Tristan

@Tristan, 기본적으로 spring은 application.properties모든 매개 변수로 하나 를 읽고 ${file_name}.properties부분적으로 정의 된 속성 세트로 여러 개 를 읽을 수 있습니다. 따라서 @PropertySource파일에 대한 또는 다른 강력한 링크를 사용하는 경우 다른 외부 파일을 만들고 해당 속성을 재정의 할 수 있습니다 (예 : from classpath:file.properties).
Mister_Jesus

23

PropertyPlaceholderConfigurer를 살펴보면 주석보다 사용하는 것이 더 명확합니다.

예 :

@Configuration
public class PropertiesConfiguration {


    @Bean
    public PropertyPlaceholderConfigurer properties() {
        final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
//        ppc.setIgnoreUnresolvablePlaceholders(true);
        ppc.setIgnoreResourceNotFound(true);

        final List<Resource> resourceLst = new ArrayList<Resource>();

        resourceLst.add(new ClassPathResource("myapp_base.properties"));
        resourceLst.add(new FileSystemResource("/etc/myapp/overriding.propertie"));
        resourceLst.add(new ClassPathResource("myapp_test.properties"));
        resourceLst.add(new ClassPathResource("myapp_developer_overrides.properties")); // for Developer debugging.

        ppc.setLocations(resourceLst.toArray(new Resource[]{}));

        return ppc;
    }

이 답변에 감사드립니다. 기본 XML 파일이없는 여러 가지 XML 구성을 가진 프로젝트에서 동일한 작업을 수행 할 수있는 방법을 알려주시겠습니까? 위의 답변은 주석 기반의 다른 프로젝트에서 저를 도왔습니다. 다시 한번 감사드립니다.
Chetan

8

이것은 스프링 부트를 사용하는 하나의 간단한 접근법입니다.

TestClass.java

@Configuration
@Profile("one")
@PropertySource("file:/{selected location}/app.properties")
public class TestClass {

    @Autowired
    Environment env;

    @Bean
    public boolean test() {
        System.out.println(env.getProperty("test.one"));
        return true;
    }
}

선택한 위치app.properties 컨텍스트

test.one = 1234

당신의 봄 부팅 응용 프로그램

@SpringBootApplication

public class TestApplication {

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

및 사전 정의 된 application.properties 컨텍스트

spring.profiles.active = one

원하는만큼 많은 구성 클래스를 작성하고 spring.profiles.active = 프로필 이름 / 이름 {쉼표로 구분} 를 설정하여 활성화 / 비활성화 할 수 있습니다.

스프링 부트가 훌륭하다는 것을 알 수 있듯이 언젠가는 익숙해 지기만하면됩니다. 필드에서도 @Value를 사용할 수 있다는 점을 언급 할 가치가 있습니다.

@Value("${test.one}")
String str;

7

나는 같은 문제가 있었다. Spring Boot application.properties 감지와 유사한 외부 파일로 시작시 내부 구성 파일을 덮어 쓸 수있는 기능을 원했습니다. 제 경우에는 애플리케이션 사용자가 저장되는 user.properties 파일입니다.

내 요구 사항 :

다음 위치에서 파일을로드합니다 (이 순서대로).

  1. 클래스 경로
  2. 현재 디렉토리 의 / config 하위 디렉토리.
  3. 현재 디렉토리
  4. 시작시 명령 줄 매개 변수에 의해 제공된 디렉토리 또는 파일 위치에서

다음 해결책을 찾았습니다.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Properties;

import static java.util.Arrays.stream;

@Configuration
public class PropertiesConfig {

    private static final Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

    private final static String PROPERTIES_FILENAME = "user.properties";

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Properties userProperties() throws IOException {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(PROPERTIES_FILENAME),
                new PathResource("config/" + PROPERTIES_FILENAME),
                new PathResource(PROPERTIES_FILENAME),
                new PathResource(getCustomPath())
        };
        // Find the last existing properties location to emulate spring boot application.properties discovery
        final Resource propertiesResource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties userProperties = new Properties();

        userProperties.load(propertiesResource.getInputStream());

        LOG.info("Using {} as user resource", propertiesResource);

        return userProperties;
    }

    private String getCustomPath() {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + PROPERTIES_FILENAME;
    }

}

이제 응용 프로그램은 클래스 경로 리소스를 사용하지만 다른 지정된 위치에서도 리소스를 확인합니다. 존재하는 마지막 자원이 선택되고 사용됩니다. 내 보트를 떠 다니는 속성 위치를 사용하기 위해 java -jar myapp.jar --properties.location = / directory / myproperties.properties로 내 앱을 시작할 수 있습니다.

여기에 중요한 세부 정보 : 속성이 설정되지 않은 경우 오류를 방지하기 위해 @Value 주석의 properties.location에 대한 기본값으로 빈 문자열을 사용합니다.

properties.location의 규칙은 다음과 같습니다. properties.location으로 속성 파일에 대한 디렉터리 또는 경로를 사용합니다.

특정 속성 만 재정의하려는 경우 setIgnoreResourceNotFound (true)가있는 PropertiesFactoryBean을 위치로 설정된 리소스 배열과 함께 사용할 수 있습니다.

이 솔루션은 여러 파일을 처리하도록 확장 할 수 있습니다.

편집하다

여기 여러 파일에 대한 내 솔루션 :) 이전과 마찬가지로 이것은 PropertiesFactoryBean과 결합 될 수 있습니다.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Map;
import java.util.Properties;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

@Configuration
class PropertiesConfig {

    private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);
    private final static String[] PROPERTIES_FILENAMES = {"job1.properties", "job2.properties", "job3.properties"};

    @Value("${properties.location:}")
    private String propertiesLocation;

    @Bean
    Map<String, Properties> myProperties() {
        return stream(PROPERTIES_FILENAMES)
                .collect(toMap(filename -> filename, this::loadProperties));
    }

    private Properties loadProperties(final String filename) {
        final Resource[] possiblePropertiesResources = {
                new ClassPathResource(filename),
                new PathResource("config/" + filename),
                new PathResource(filename),
                new PathResource(getCustomPath(filename))
        };
        final Resource resource = stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .reduce((previous, current) -> current)
                .get();
        final Properties properties = new Properties();

        try {
            properties.load(resource.getInputStream());
        } catch(final IOException exception) {
            throw new RuntimeException(exception);
        }

        LOG.info("Using {} as user resource", resource);

        return properties;
    }

    private String getCustomPath(final String filename) {
        return propertiesLocation.endsWith(".properties") ? propertiesLocation : propertiesLocation + filename;
    }

}

좋은 해결 방법입니다. java8 구조처럼! 어쨌든 나는 하나가 아닌 여러 개의 속성 빈이 필요하기 때문에 그것을 사용할 수 없습니다. 내 EDITS가 표시되면 내 해결 방법이 내 사용 사례와 매우 유사하고 깔끔합니다.
nir

난 그냥 완성도, 여러 파일에 대한 버전을 게시)
mxsb

6

스프링 부트를 사용하면 다양한 환경에 대해 작성하기 위해 다른 프로필을 작성할 수 있습니다. 예를 들어 프로덕션, qa 및 로컬 환경에 대해 별도의 속성 파일을 가질 수 있습니다.

내 로컬 컴퓨터에 따른 구성이있는 application-local.properties 파일은

spring.profiles.active=local

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=users
spring.data.mongodb.username=humble_freak
spring.data.mongodb.password=freakone

spring.rabbitmq.host=localhost
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672

rabbitmq.publish=true

마찬가지로 application-prod.properties 및 application-qa.properties를 원하는만큼 많은 속성 파일을 작성할 수 있습니다.

그런 다음 다른 환경에서 응용 프로그램을 시작하는 스크립트를 작성하십시오.

mvn spring-boot:run -Drun.profiles=local
mvn spring-boot:run -Drun.profiles=qa
mvn spring-boot:run -Drun.profiles=prod

5

나는 이것과 비슷한 문제가 있었고 마침내 원인을 알아 냈습니다. application.properties 파일에 잘못된 소유권과 rwx 속성이 있습니다. 따라서 tomcat이 시작되었을 때 application.properties 파일은 올바른 위치에 있었지만 다른 사용자가 소유했습니다.

$ chmod 766 application.properties

$ chown tomcat application.properties

비슷한 문제가 있다고 생각합니다. opt 폴더에 바람둥이를 설치했습니다. 응용 프로그램 파일을 어디에 배치 했습니까? 폴더 속성도 변경해야합니까?
anakin59490

3

여러 파일을 정의 할 수있는 @mxsb 솔루션의 수정 된 버전이며 제 경우에는 yml 파일입니다.

내 application-dev.yml에 -dev.yml이있는 모든 yml을 주입 할 수있는이 구성을 추가했습니다. 이것은 또한 특정 파일의 목록 일 수 있습니다. "classpath : /test/test.yml,classpath : /test2/test.yml"

application:
  properties:
    locations: "classpath*:/**/*-dev.yml"

이것은 속성 맵을 얻는 데 도움이됩니다.

@Configuration

public class PropertiesConfig {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfig.class);

@Value("${application.properties.locations}")
private String[] locations;

@Autowired
private ResourceLoader rl;

@Bean
Map<String, Properties> myProperties() {
    return stream(locations)
            .collect(toMap(filename -> filename, this::loadProperties));
}

private Properties loadProperties(final String filename) {

    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .forEach(propertySource -> {
                    Map source = ((MapPropertySource) propertySource).getSource();
                    properties.putAll(source);
                });

        return properties;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
}

그러나 내 경우와 마찬가지로 각 프로필에 대해 yml 파일을 분할하고로드하여 Bean 초기화 전에 스프링 구성에 직접 삽입해야합니다.

config
    - application.yml
    - application-dev.yml
    - application-prod.yml
management
    - management-dev.yml
    - management-prod.yml

... 당신은 아이디어를 얻습니다

구성 요소가 약간 다릅니다

@Component
public class PropertiesConfigurer extends     PropertySourcesPlaceholderConfigurer
    implements EnvironmentAware, InitializingBean {

private final static Logger LOG = LoggerFactory.getLogger(PropertiesConfigurer.class);

private String[] locations;

@Autowired
private ResourceLoader rl;
private Environment environment;

@Override
public void setEnvironment(Environment environment) {
    // save off Environment for later use
    this.environment = environment;
    super.setEnvironment(environment);
}

@Override
public void afterPropertiesSet() throws Exception {
    // Copy property sources to Environment
    MutablePropertySources envPropSources = ((ConfigurableEnvironment) environment).getPropertySources();
    envPropSources.forEach(propertySource -> {
        if (propertySource.containsProperty("application.properties.locations")) {
            locations = ((String) propertySource.getProperty("application.properties.locations")).split(",");
            stream(locations).forEach(filename -> loadProperties(filename).forEach(source ->{
                envPropSources.addFirst(source);
            }));
        }
    });
}


private List<PropertySource> loadProperties(final String filename) {
    YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    try {
        final Resource[] possiblePropertiesResources = ResourcePatternUtils.getResourcePatternResolver(rl).getResources(filename);
        final Properties properties = new Properties();
        return stream(possiblePropertiesResources)
                .filter(Resource::exists)
                .map(resource1 -> {
                    try {
                        return loader.load(resource1.getFilename(), resource1);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).flatMap(l -> l.stream())
                .collect(Collectors.toList());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

}


3

application.properties 파일에 지정된 값을 재정의하려면 애플리케이션을 실행하는 동안 활성 프로필을 변경하고 프로필에 대한 애플리케이션 속성 파일을 만들 수 있습니다. 예를 들어 활성 프로필 "override"를 지정한 다음 / tmp 아래에 "application-override.properties"라는 새 응용 프로그램 속성 파일을 만들었다 고 가정하면 다음을 실행할 수 있습니다.

java -jar yourApp.jar --spring.profiles.active="override" --spring.config.location="file:/tmp/,classpath:/" 

spring.config.location에 지정된 값은 역순으로 평가됩니다. 따라서 제 예에서는 classpat가 먼저 평가 된 다음 파일 값이 평가됩니다.

jar 파일과 "application-override.properties"파일이 현재 디렉토리에 있으면 실제로 간단히 사용할 수 있습니다.

java -jar yourApp.jar --spring.profiles.active="override"

Spring Boot가 속성 파일을 찾기 때문에


1
Spring에 "override"프로파일을 활성 프로파일로 사용하도록 지시합니다. 실제로 application.yml 또는 application.properties 파일에 지정된 값을
능가

내 경우에는 모든 구성 파일 .ymal 또는 .properties 폴더 내부를 살펴볼 것입니다. 제 경우에는 application-profile.yml 만 넣은 다음 올바르게 걸립니다. @acaruci 감사합니다. 멋진 여행이었습니다
Ahmed Salem

0

나는 이것이 따라야 할 유용한 패턴이라는 것을 알았습니다.

@RunWith(SpringRunner)
@SpringBootTest(classes = [ TestConfiguration, MyApplication ],
        properties = [
                "spring.config.name=application-MyTest_LowerImportance,application-MyTest_MostImportant"
                ,"debug=true", "trace=true"
        ]
)

여기서는 "application-MyTest_LowerImportance.yml"및 "application-MyTest_MostImportant.yml"을 사용하기 위해 "application.yml"사용을 재정의합니다
(Spring은 .properties 파일도 찾습니다).

추가 보너스로 별도의 줄에 디버그 및 추적 설정이 포함되어 있으므로 필요한 경우 주석 처리 할 수 ​​있습니다.]

디버그 / 추적은 Spring이로드하는 모든 파일과로드하려는 파일의 이름을 덤프하므로 매우 유용합니다.
런타임시 콘솔에 다음과 같은 줄이 표시됩니다.

TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.properties' (file:./config/application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.xml' (file:./config/application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yml' (file:./config/application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant.yaml' (file:./config/application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.properties' (file:./config/application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.xml' (file:./config/application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yml' (file:./config/application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_LowerImportance.yaml' (file:./config/application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.properties' (file:./application-MyTest_MostImportant.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.xml' (file:./application-MyTest_MostImportant.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yml' (file:./application-MyTest_MostImportant.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_MostImportant.yaml' (file:./application-MyTest_MostImportant.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.properties' (file:./application-MyTest_LowerImportance.properties) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.xml' (file:./application-MyTest_LowerImportance.xml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yml' (file:./application-MyTest_LowerImportance.yml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./application-MyTest_LowerImportance.yaml' (file:./application-MyTest_LowerImportance.yaml) resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.xml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/config/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_MostImportant.yml' (classpath:/application-MyTest_MostImportant.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_MostImportant.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.properties' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.xml' resource not found
DEBUG 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Loaded config file 'file:/Users/xxx/dev/myproject/target/test-classes/application-MyTest_LowerImportance.yml' (classpath:/application-MyTest_LowerImportance.yml)
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'classpath:/application-MyTest_LowerImportance.yaml' resource not found
TRACE 93941 --- [   main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application-MyTest_MostImportant-test.properties' (file:./config/application-MyTest_MostImportant-test.properties) resource not found

-1

이것을 알아 내려고 할 때 많은 문제가 발생했습니다. 여기 내 설정이 있습니다.

개발자 환경 : Windows 10, Java : 1.8.0_25, Spring Boot : 2.0.3.RELEASE, Spring : 5.0.7.RELEASE

내가 찾은 것은 봄이 "구성을위한 적절한 기본값"이라는 개념을 고수하고 있다는 것입니다. 이것이 의미하는 바는 전쟁 파일의 일부로 모든 속성 파일을 가져야한다는 것입니다. 그런 다음 "--spring.config.additional-location"명령 줄 속성을 사용하여 외부 속성 파일을 가리 키도록 재정의 할 수 있습니다. 그러나 속성 파일이 원래 war 파일의 일부가 아닌 경우 작동하지 않습니다.

데모 코드 : https://github.com/gselvara/spring-boot-property-demo/tree/master

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.