Spring boot 1.5.3 source code analysis (IV): Custom Conditional annotation

Keywords: Java Attribute Spring

;

The book follows.
I've talked about the principle of condition before. In fact, it's easy to customize a condition. You only need to implement the SpringBootCondition class, and override the com.example.demo.condition.OnLblCondition#getMatchOutcome method.

Let's write a simple example: judge whether to load the bean according to the content in the property configuration file.

First, define an annotation with two contents: one is the KEY of the attribute file, and the other is value. We need to implement that the value of the property file is the same as the specified value before creating the bean.

package com.example.demo.condition;

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnLblCondition.class)
public @interface ConditionalOnLbl {
    String key();
    String value();
}

To customize the implementation class OnLblCondition of SpringBootCondition:

package com.example.demo.condition;

import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

public class OnLblCondition extends SpringBootCondition {

    @Override
    public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionalOnLbl.class.getName());
        Object key = annotationAttributes.get("key");//
        Object value = annotationAttributes.get("value");
        if(key == null || value == null){
            return new ConditionOutcome(false, "error");
        }

        //Get value in environment
        String key1 = context.getEnvironment().getProperty(key.toString());
        if (value.equals(key1)) {//Returns true if the value in the environment is the same as the specified value
            return new ConditionOutcome(true, "ok");
        }
        return new ConditionOutcome(false, "error");
    }
}

Then define any class:

@Slf4j
public class MyConditionService {
    public void say() {
        log.info("MyConditionService init. ");
    }
}

OK, the condition has been customized. The next step is how to use:

@Configuration
@Slf4j
public class MySpringBootConfig {
    @ConditionalOnLbl(key = "com.lbl.mycondition", value = "lbl")
    @ConditionalOnClass(MyConditionService.class)
    @Bean
    public MyConditionService initMyConditionService() {
        log.info("MyConditionService Loaded.");
        return new MyConditionService();
    }

To load the bean s of MyConditionService into the spring container, you need to meet the following two conditions:
1. The property file is configured com.lbl.mycondition=lbl
2. You can load the MyConditionService class

All right, let's application.properties Add configuration to file com.lbl.mycondition=lbl
Start the project, and you can see the log: MyConditionService is loaded.
hold application.properties In the file com.lbl.mycondition If you remove or change values, the above logs will not be printed, that is, MyConditionService bean will not be created

end.

Posted by bweekly on Sat, 30 May 2020 09:07:37 -0700