programing

스프링 부트 - 속성이 설정되지 않은 경우 감지 및 종료하시겠습니까?

jooyons 2023. 7. 24. 22:28
반응형

스프링 부트 - 속성이 설정되지 않은 경우 감지 및 종료하시겠습니까?

필요한 속성이 application.properties 파일이나 다른 속성 소스에 설정되어 있지 않은 경우 시작 시 Spring Boot 웹 응용 프로그램을 중단할 수 있는 방법이 있습니까?지금 당장은 속성이 다른 속성에 포함된 경우 Spring Boot은 단순히 대체를 피하는 것으로 보입니다.

예를 들어, application.properties 파일에서 다음과 같은 줄을 사용합니다.

quartz.datasource.url=jdbc:hsqldb:${my.home}/database/my-jobstore

현재 "my.home"이 다른 곳에서 설정되지 않은 경우 Spring Boot는 문자 그대로 URL을 "jdbc:hsqldb:${my.home}/database/my-jobstore"(대체 없음)로 설정합니다.

속성이 있는 경우 응용 프로그램을 시작하지 못하게 하고 싶습니다.my.home다른 곳에 설정되지 않았습니다.

친숙한 예외를 발생시키려면 속성에 기본 null 값을 입력하면 됩니다. Property 메서드를 선택한 후 예외를 발생시킵니다.

@Component
public static class ConfigurationGuard implements InitializingBean {

@Value("${my.home:#{null}}")
private String myHomeValue;

public void afterPropertiesSet() {
    if (this.myHomeValue == null or this.myHomeValue.equals("${my.home}") {
          throw new IllegalArgumentException("${my.home} must be configured");
    }
 }
}

간단한 것으로 콩 만들기@Value(${my.home})주석이 달린 필드. - 그런 다음 스프링이 해당 값을 주입하려고 시도하고 실패하므로 값이 없을 때 중지됩니다.


그저.@Value(${my.home}) private String myHomeValue;물론 일반적인(부팅이 아닌) 스프링 애플리케이션에 충분합니다!그러나 Boot에 결측값을 처리할 수 있는 다른 구성이 있는지 모르겠습니다.PostCreation 메서드에서 해당 값을 확인할 수 있는 것보다 다른 오류 관리가 있는 경우

@Component
public static class ConfigurationGuard implements InitializingBean {

   @Value(${my.home})
   private String myHomeValue;

   /**
    * ONLY needed if there is some crude default handling for missing values!!!!
    *
    * So try it first without this method (and without implements InitializingBean)
    */
   public void afterPropertiesSet() {
      if (this.myHomeValue == null or this.myHomeValue.equals("${my.home}") {
          throw new IllegalArgumentException("${my.home} must be configured");
      }
   }

}

현재 버전의 Spring Boot(1.5.x, 2.0.x, 2.1.x)에서 기본 동작은 자리 표시자를 확인할 수 없는 경우 예외를 던지는 것입니다.

다음과 같은 예외가 있을 것입니다.

원인: java.lang.잘못된 인수예외:값 "${app"에서 자리 표시자 'app.foo.undefined'을(를) 확인할 수 없습니다.foo.foo}"

유형의 콩이 작용하기 때문입니다.PropertySourcesPlaceholderConfigurer(spring-context에서)는 SpringBoot, 이 클래스에 자동으로 등록됩니다. 기본적으로 속성은ignoreUnresolvablePlaceholdersPropertySourcesPlaceholderConfigurerfalse로 설정됩니다. 즉, 자리 표시자가 확인되지 않은 경우(네스트되었는지 여부에 관계없이) 예외를 던져야 합니다.

작동하기는 하지만 사전 정의된 이름에만 작동하고 누군가가 바뀌면 조용히 확인을 중단하기 때문에 최우선 답변의 접근 방식은 다소 취약하다고 생각합니다.quartz.datasource.url구성에서 다른 확장을 사용합니다.

이상적으로, 는 이 가치가false 음같 구문 분석때 받할검 으를려면과 같은 내 구성을 분석할 때 도매 application.properties또는 YAML 변형이지만 이러한 경우에는 하드 코딩되어 있습니다.이것은 불행하게도 다음과 같은 문자열을 남깁니다.${FOO}확장되지 않은 형태로 만약에FOO찾을 수 없으므로 문제 해결이 매우 고통스럽습니다.특히 암호와 같이 로그에 쉽게 나타나지 않는 필드의 경우가 그렇습니다.

가 바꿀 에 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠignoreUnresolvablePlaceholdersBoot의에, Spring Boot을 .PropertySource및 " 현및다 과새정구의문구은같"와같은 ${!FOO}나내다타를 FOO환경 변수 또는 다이로 존재해야 합니다.(OP는 언급하지 않았습니다.my.home는 환경 변수이지만 아래 코드는 환경 변수용입니다.)

첫로째번.EnvironmentPostProcessor 정의 를 합니다.PropertySource . 것이.StrictSystemEnvironmentProcessor.java 사용자구유뿐지만아니이수라를행다니합할현정을의의 구현을 하고 있을 만 아니라 이 합니다.PropertySource:

package some.package;

@Order(Ordered.LOWEST_PRECEDENCE)
class StrictSystemEnvironmentProcessor implements EnvironmentPostProcessor {

    private static final String PROPERTY_SOURCE_NAME = "STRICT_" + StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        if (environment.getPropertySources().contains(PROPERTY_SOURCE_NAME)) {
            return;
        }

        SystemEnvironmentPropertySource delegate = (SystemEnvironmentPropertySource)environment.getPropertySources()
                .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);

        environment.getPropertySources().addLast(new StrictSystemEnvironmentPropertySource(delegate));
    }

    private static class StrictSystemEnvironmentPropertySource extends SystemEnvironmentPropertySource {

        public StrictSystemEnvironmentPropertySource(SystemEnvironmentPropertySource delegate) {
            super(PROPERTY_SOURCE_NAME, delegate.getSource());
        }

        @Override
        public Object getProperty(String name) {
            if (name.startsWith("!")) {
                String variableName = name.substring(1);
                Object property = super.getProperty(variableName);
                if (property != null) {
                    return property;
                }

                throw new IllegalStateException("Environment variable '" + variableName + "' is not set");
            }
            return null;
        }
    }

}

돌아오는 대신에null로 시이름대예발해생다니로 합니다.!.

것이.META-INF/spring.factories Spring이 의 또한스초위필해요합다니기하기화이프링izes▁our다를 초기화하기 위해 합니다.EnvironmentPostProcessor:

org.springframework.boot.env.EnvironmentPostProcessor=some.package.StrictSystemEnvironmentProcessor

그 나는 내 구성에 을 러면이제구모환변경대다같쓸있수다습니이로 쓸 수.${!FOO}엄격한 존재 확인을 받기 위해.

다음을 생성할 수도 있습니다.@ConfigurationProperties으로장식니다합콩▁it다니합,▁bean로 장식합니다.@Validated그리고.@NotNull 시 때 시작시값없또때예발다생니합외가을는이또(▁this▁during다▁the▁when▁an니▁exception발▁throw▁will▁startup합생▁is는or▁value가예외시) 예외가 발생합니다.null 예:

@Validated
@ConfigurationProperties("my")
public class MyProperties {
    @NotNull  
    private String home;

    // getter/setter, or constructor. See @ConstructorBinding.
}

참조: Spring Boot 2.6 - @ConfigurationProperties Validation.

있니다습을 추가해야 할 .spring-boot-starter-validation또는 프로젝트에 따라 다른 검증자를 선택할 수 있습니다.

그런 다음 필요할 때 종속성으로 제공하면 됩니다. 예를 들어,

@Component
public class AnotherBean {
    private final MyProperties myProps;

    public AnotherBean(MyProperties myProps) {
        this.myProps = myProps;
    }

    // some code that uses myProps.getHome()
}

언급URL : https://stackoverflow.com/questions/31528697/spring-boot-detect-and-terminate-if-property-not-set

반응형