복붙노트

[SPRING] 조건부로 콩을 선언 할 수 있습니까?

SPRING

조건부로 콩을 선언 할 수 있습니까?

조건부로 Spring 빈을 선언 할 수있는 방법이 있는가?

<bean class="path.to.the.class.MyClass" if="${1+2=3}" />

프로필을 사용하는 대신 유용 할 것입니다. 나는 특정한 유스 케이스를 염두에두고 있지는 않지만 나에게왔다.

해결법

  1. ==============================

    1.Spring4의 @Conditional이나 SpringBoot의 @ConditionalOnProperty를 사용할 수 있습니다.

    Spring4의 @Conditional이나 SpringBoot의 @ConditionalOnProperty를 사용할 수 있습니다.

    먼저 ConditionContext가 환경에 액세스 할 수있는 Condition 클래스를 만듭니다.

    public class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, 
                               AnnotatedTypeMetadata metadata) {
            Environment env = context.getEnvironment();
            return null != env 
                   && "true".equals(env.getProperty("server.host"));
        }
    }
    

    그런 다음 bean에 주석을 달아 라.

    @Bean
    @Conditional(MyCondition.class)
    public ObservationWebSocketClient observationWebSocketClient(){
        //return bean
    }
    

    @ConditionalOnProperty (name = "server.host", havingValue = "localhost")

    그리고 abcd.properties 파일에서,

    server.host=localhost
    
  2. ==============================

    2.나는 그런 일을위한 발췌 문장이있다. 주석에 설정된 속성의 값을 검사하므로 다음과 같은 것을 사용할 수 있습니다.

    나는 그런 일을위한 발췌 문장이있다. 주석에 설정된 속성의 값을 검사하므로 다음과 같은 것을 사용할 수 있습니다.

    @ConditionalOnProperty(value="usenew", on=false, propertiesBeanName="myprops")
    @Service("service")
    public class oldService implements ServiceFunction{
        // some old implementation of the service function.
    }
    

    동일한 이름의 다른 빈을 정의 할 수도 있습니다.

    @ConditionalOnProperty(value="usenew", on=true, propertiesBeanName="myprops")
    @Service("service")
    public class newService implements ServiceFunction{
        // some new implementation of the service function.
    }
    

    이 두 가지는 동시에 선언 할 수 있으므로 속성이 켜져 있는지 여부에 따라 구현이 다른 "서비스"bean을 가질 수 있습니다.

    자체 스 니펫 :

    /**
     * Components annotated with ConditionalOnProperty will be registered in the spring context depending on the value of a
     * property defined in the propertiesBeanName properties Bean.
     */
    
    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Conditional(OnPropertyCondition.class)
    public @interface ConditionalOnProperty {
        /**
         * The name of the property. If not found, it will evaluate to false.
         */
        String value();
        /**
         * if the properties value should be true (default) or false
         */
        boolean on() default true;
        /**
         * Name of the bean containing the properties.
         */
        String propertiesBeanName();
    }
    
    /**
     * Condition that matches on the value of a property.
     *
     * @see ConditionalOnProperty
     */
    class OnPropertyCondition implements ConfigurationCondition {
        private static final Logger LOG = LoggerFactory.getLogger(OnPropertyCondition.class);
    
        @Override
        public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) {
            final Map attributes = metadata.getAnnotationAttributes(ConditionalOnProperty.class.getName());
            final String propertyName = (String) attributes.get("value");
            final String propertiesBeanName = (String) attributes.get("propertiesBeanName");
            final boolean propertyDesiredValue = (boolean) attributes.get("on");
    
            // for some reason, we cannot use the environment here, hence we get the actual properties bean instead.
            Properties props = context.getBeanFactory().getBean(propertiesBeanName, Properties.class);
            final boolean propValue = parseBoolean(props.getProperty(propertyName, Boolean.toString(false)));
            LOG.info("Property '{}' resolved to {}, desired: {}", new Object[] { propertyName, propValue, "" + propertyDesiredValue });
            return propValue == propertyDesiredValue;
        }
        /**
         * Set the registration to REGISTER, else it is handled during  the parsing of the configuration file
         * and we have no guarantee that the properties bean is loaded/exposed yet
         */
        @Override
        public ConfigurationPhase getConfigurationPhase() {
            return ConfigurationPhase.REGISTER_BEAN;
        }
    }
    
  3. from https://stackoverflow.com/questions/39857804/can-we-declare-spring-bean-conditionally by cc-by-sa and MIT license