programing

Spring @ConditionalOnProperty, 누락된 경우에만 일치시키는 방법

goodsources 2023. 6. 30. 22:19
반응형

Spring @ConditionalOnProperty, 누락된 경우에만 일치시키는 방법

두 가지 공장 방식이 있습니다.

@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}

그리고.

@Bean
@ConditionalOnProperty("some.property.text", matchIfMissing=true)
public Apple createAppleY() {}

"some.property.text" 속성이 전혀 없는 경우 - 두 번째 메서드는 정상적으로 작동하고 첫 번째 메서드는 무시되며, 이는 원하는 동작입니다.

일부 문자열이 "some.property.text"로 설정된 경우 - 두 가지 방법 모두 Apple 개체를 생성하는 데 유효한 것으로 간주되므로 "No Qualified bean of type" 오류와 함께 응용 프로그램이 실패합니다.

우리가 부동산에 대한 가치가 있을 경우 공장 방식으로 간주되는 두 번째 방법을 피할 수 있습니까?특히 주석으로만 가능한가요?

저는 같은 문제에 직면해 있었고, 여기 제 해결책이 있습니다.

@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}

@Bean
@ConditionalOnProperty("some.property.text", matchIfMissing=true, havingValue="value_that_never_appears")
public Apple createAppleY() {}

사용할 수 있습니다.NoneNestedConditions하나 이상의 중첩 조건을 무효화합니다.이와 같은 것:

class NoSomePropertyCondition extends NoneNestedConditions {

    NoSomePropertyCondition() {
        super(ConfigurationPhase.PARSE_CONFIGURATION);
    }

    @ConditionalOnProperty("some.property.text")
    static class SomePropertyCondition {

    }

}

그런 다음 빈 방법 중 하나에서 이 사용자 정의 조건을 사용할 수 있습니다.

@Bean
@ConditionalOnProperty("some.property.text")
public Apple createAppleX() {}

@Bean
@Conditional(NoSomePropertyCondition.class)
public Apple createAppleY() {}

원 업맨십의 정신으로, 여기 더 재사용 가능한 주석이 있습니다.

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Conditional(ConditionalOnMissingProperty.MissingPropertyCondition.class)
public @interface ConditionalOnMissingProperty {

    String PROPERTY_KEYS = "propertyKeys";

    @AliasFor(PROPERTY_KEYS)
    String[] value() default {};

    @AliasFor("value")
    String[] propertyKeys() default {};

    class MissingPropertyCondition extends SpringBootCondition {
        @Override
        public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
            String[] keys = (String[]) metadata.getAnnotationAttributes(ConditionalOnMissingProperty.class.getName()).get(PROPERTY_KEYS);
            if (keys.length > 0) {
                boolean allMissing = true;
                for (String key : keys) {
                    String propertyValue = context.getEnvironment().getProperty(key);
                    String propertyValueList = context.getEnvironment().getProperty(key + "[0]"); //in case of list
                    allMissing &= (StringUtils.isEmpty(propertyValue) && StringUtils.isEmpty(propertyValueList));
                }
                if (allMissing) {
                    return new ConditionOutcome(true, "The following properties were all null or empty in the environment: " + Arrays.toString(keys));
                }
                return new ConditionOutcome(false, "one or more properties were found.");
            } else {
                throw new RuntimeException("expected method annotated with " + ConditionalOnMissingProperty.class.getName() + " to include a non-empty " + PROPERTY_KEYS + " attribute");
            }
        }
    }
}

주석이 달린 빈 또는 구성은 하나 이상의 언급된 속성이 모두 존재하지 않을 때 활성화됩니다.

@ConditionalOnMissingProperty({"app.foo.bar"})
@Configuration
public class SomeConfiguration {
  //... won't run if there is an app.foo.bar property with non-empty contents.
}

나중에 잘못된 결과에 더 포괄적인 보고를 추가하면 여기에 추가하겠습니다.

언급URL : https://stackoverflow.com/questions/47561048/spring-condiitonalonproperty-how-to-match-only-if-missing

반응형