madplay / madplay.github.io

오늘도 MadPlay!
https://madplay.github.io
MIT License
18 stars 2 forks source link

Spring Cloud Config: Spring Boot 2.4 버전에서의 변경사항 #132

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Spring Cloud Config: Spring Boot 2.4 버전에서의 변경사항

스프링 부트 2.4 버전에서 적용된 Spring Cloud Config 관련 변경사항

https://madplay.github.io/post/changes-in-spring-cloud-config-from-spring-boot-2-4

dasog94 commented 3 years ago

spring: config: import: "optional:configserver:http://myconfigserver.com/" cloud: config: name: my-config profile: dev

이 부분에서 cloud.config.name을 통해 server의 yml 이름을 찾는게 아니라 spring.application.name을 통해 찾는 것 같습니다.

spring cloud config 공부하는데 많은 도움이 되는 글을 올려주셔서 감사합니다. 다른 분들도 많이 참고하실텐데 한번 확인 부탁 드립니다.

madplay commented 3 years ago

@dasog94 안녕하세요. 만나서 반갑습니다 :)

말씀하신 부분도 맞습니다.ㅎ 다만, spring-cloud-config의 Client 가이드의 Remote Configuration 부분을 보시면,

"You can override all of them by setting spring.cloud.config. (where is name, profile or label). spring.cloud.config.*를 설정하여 모두 재정의할 수 있다. (*는 name, profile, label가 해당)

의 내용을 확인해보실 수 있습니다.

코드상으로는 Spring Cloud의 2020.0.2 버전 기준으로, Spring Cloud Config 클라이언트의 ConfigServerConfigDataLocationResolver.java에서 확인하실 수 있습니다.

protected ConfigClientProperties loadProperties(ConfigDataLocationResolverContext context) {
    Binder binder = context.getBinder();
    BindHandler bindHandler = getBindHandler(context);
    ConfigClientProperties configClientProperties = binder
                .bind(ConfigClientProperties.PREFIX, Bindable.of(ConfigClientProperties.class), bindHandler)
                .orElseGet(ConfigClientProperties::new);
    if (!StringUtils.hasText(configClientProperties.getName())) {
        // default to spring.application.name if name isn't set
        String applicationName = binder.bind("spring.application.name", Bindable.of(String.class), bindHandler)
                    .orElse("application");
        configClientProperties.setName(applicationName);
    }
    return configClientProperties;
}

위 코드상에서 ConfigClientProperties.PREFIX의 값은 "spring.cloud.config"입니다.

따라서 spring.cloud.config.name으로 설정된 값이 configClientProperties 에 할당이 되는데요. 만일 설정된 name 값이 있다면, 중간의 if문 내부 코드는 수행되지 않습니다. 즉, 결과적으로 설정된 이름값은 spring.application.name 이 아닌 spring.cloud.config.name을 참조하게 됩니다.

좋은 질문 감사합니다. 말씀 주신 부분도 저를 비롯하여 같이 공부하시는 다른 분들께 많이 도움 되겠어요. 블로그 글에서 잘못된 내용이 있으시면 언제든지 말씀해 주세요.

감사합니다~ 🚀

dasog94 commented 3 years ago

안녕하세요, 답변 감사합니다. 제 설정에 오류가 있었던 것 같습니다. 다시 해보니 되더군요. 죄송합니다.. ㅎㅎ 문서를 좀 더 확인하는 습관을 들여야겠습니다. 감사합니다.

궁금한 게 생겨 문의 드립니다. 2.4 버전부터는 bootstrap을 따로 dependency 추가하여 사용하지 않고는 local config에서 remote repo에서 읽어온 값을 override 할 수 없게 된 것 같습니다.(테스트 해보진 않고 자료를 찾아본 것이라 틀릴 수도 있습니다.) 혹시 별도의 local config의 우선순위를 높일 수 있는 방법이 있는 지 궁금합니다.

제 셍각엔 spring cloud config가 local 개발 시엔 별도의 local repo를 구성하여 개발하라는 것 같긴한데, 혹시나 방법이 있는 지 궁금합니다.

dasog94 commented 3 years ago

bootstrap을 사용하지 않고 테스트는 진행해보았는데 작동을 하지 않더군요... 이것도 제 실수일 수 있겠지만, 3.0.4 문서에는 Overriding the Values of Remote Properties에 대한 부분이 없긴 하더군요.

madplay commented 3 years ago

네, 안녕하세요.

cloud.config.name과 cloud.config.profile`을 다 지워도 안 되시나요~?

spring:
  application:
    name: myConfig
  config:
    import: "optional:configserver:http://myconfigserver.com/"

또는 로컬 레포를 구성하기 어려운 환경에서는 아래와 같이 클래스와 yml 파일을 별도로 만들어서 테스트 용으로 사용하는 것은 어떨까요?

@Configuration
public class MyConfiguration {

    @Configuration
    @Profile("local")
    @PropertySource(value = "classpath:application-testConfig-local.yml")
    static class DefaultConfig {
        // member fields
    }
}
dasog94 commented 3 years ago

좋은 방법을 제시해주셔서 감사합니다. 두 방법을 참고해서 사용해보겠습니다. 많은 도움이 되었습니다!!