IT박스

스프링 부트 및 여러 외부 구성 파일

itboxs 2020. 8. 5. 08:02
반응형

스프링 부트 및 여러 외부 구성 파일


클래스 경로에서로드하려는 여러 개의 속성 파일이 있습니다. /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있습니다. 봄마다 부팅 문서 구성 폴더는 classpath에 있어야합니다. 그러나 doc의 applicaiton.properties모든 속성 만 재정의하는 경우 doc에서 명확하지 않습니다 .

테스트 할 때 만 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>

이것이 응용 프로그램을로드하는 동안 파일과 클래스 경로를 구분하는 방법입니다.
EDITS :

//psuedo code

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

위의 해결 방법을 사용하지 않으려는 경우 파일과 마찬가지로 클래스 경로의 모든 외부 구성 파일을 스프링보다 우선 application.properties합니다.


Spring Boot를 사용하는 경우 속성은 다음 순서로로드됩니다 ( Spring Boot 참조 안내서의 외부 구성 참조).

  1. 명령 줄 인수
  2. Java 시스템 특성 (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 로의 행동 변화입니다.


Spring 부트를 사용하면 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에서 가치를 얻습니다.


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;
    }

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.getProperties()).

  • OS 환경 변수.

  • RandomValuePropertySource속성이 무작위로만있는 A. *.

  • 패키지화 된 jar ( application-{profile}.properties및 YAML 변형) 외부의 프로파일 특정 응용 프로그램 특성 .

  • jar 내부에 패키지 된 프로파일 특정 응용 프로그램 속성 ( application-{profile}.properties및 YAML 변형).

  • 패키징 된 jar 이외의 응용 프로그램 속성 ( application.properties및 YAML 변형)

  • 항아리 안에 패키지 된 응용 프로그램 속성 ( application.properties및 YAML 변형)

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

외부 특성 파일을 지정하려면 다음 옵션에 관심이 있어야합니다.

  • 패키지화 된 jar ( application-{profile}.properties및 YAML 변형) 외부의 프로파일 특정 응용 프로그램 특성 .

  • 패키징 된 jar 이외의 응용 프로그램 속성 ( application.properties및 YAML 변형)

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

이 3 가지 옵션 중 하나만 사용하거나 요구 사항에 따라 조합 할 수 있습니다.
예를 들어 프로필 별 속성 만 사용하는 매우 간단한 경우에는 충분하지만 다른 경우에는 프로필 별 속성, 기본 속성 및을 모두 사용할 수 있습니다 @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에서 spring.config.location사용하는 기본 위치를 문서에 명시된대로 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파일을 명시 적으로 지정해야합니다. 파일
을 패키지화하지 않는 uber 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 기본 위치에 있고 기본 위치를 덮어 쓰지 않고 확장하므로 마지막 예제에서는 필수가 아닙니다.


나는 같은 문제가 있었다. 스프링 부트 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;
    }

}

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

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;

스프링 부트를 사용하면 환경에 따라 다른 프로파일을 작성할 수 있습니다. 예를 들어 프로덕션, 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

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

$ chmod 766 application.properties

$ chown tomcat application.properties

여러 파일을 정의 할 수있는 @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);
    }
}

}


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가 속성 파일을 찾으므로


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

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

여기서는 "application.yml"을 사용하여 "application-MyTest_LowerImportance.yml"과 "application-MyTest_MostImportant.yml"을 사용하도록 재정의합니다
(봄도 .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

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

개발 환경 : Windows 10, Java : 1.8.0_25, 스프링 부트 : 2.0.3.RELEASE, 스프링 : 5.0.7.RELEASE

내가 찾은 것은 스프링이 "Sensible defaults for configuration"이라는 개념을 고수하고 있다는 것입니다. 이것이 의미하는 것은 모든 속성 파일을 war 파일의 일부로 가져야한다는 것입니다. 그런 다음 "--spring.config.additional-location"명령 줄 속성을 사용하여 외부 속성 파일을 가리 키도록 재정의 할 수 있습니다. 그러나 특성 파일이 원래 war 파일의 일부가 아닌 경우 작동하지 않습니다.

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

참고 URL : https://stackoverflow.com/questions/25855795/spring-boot-and-multiple-external-configuration-files

반응형