SpringBoot 条件注解
本文分析基于SpringBoot2.5.7版本进行分析,SpringBoot 条件注解基于SpringFramework4.0注解Conditional、Condition来实现。
SpringBoot 常用条件注解
注解 | 条件判断类 | 备注 |
---|---|---|
@ConditionalOnClass | OnClassCondition | 如果Classpath 存在匹配到class,就创建 |
@ConditionalOnMissingClass | OnClassCondition | 如果Classpath 不存在匹配到class,就创建 |
@ConditionalOnBean | OnBeanCondition | 如果Spring容器中 存在匹配到Bean,就创建 |
@ConditionalOnMissingBean | OnBeanCondition | 如果Spring容器 存在匹配到Bean,就创建 |
@ConditionalOnProperty | OnPropertyCondition | 如果Spring容器 存在匹配到属性,就创建 |
@ConditionalOnResource | OnResourceCondition | 如果ClassPath下存在匹配到resource,就创建 |
@ConditionalOnWebApplication | OnWebApplicationCondition | 如果应用类型不满足type(ANY、SERVLET、REACTIVE),就创建 |
@ConditionalOnNotWebApplication | OnWebApplicationCondition | 如果应用类型不满足type(ANY、SERVLET、REACTIVE),就创建 |
@ConditionalOnExpression | OnExpressionCondition | 基于SpringEL表达式进行判断,如果true就创建 |
自定义条件注解
- 编写条件Class继承Condition或者Condition子类SpringBootCondition
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
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 MyOnCondition extends SpringBootCondition {
private String defaultValue = "myCondition";
@Override
//关键点:实现业务逻辑判断
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map<String, Object> map = metadata.getAnnotationAttributes(MyConditional.class.getName());
String value = String.valueOf(map.get("value"));
if (defaultValue.equals(value)) {
return ConditionOutcome.match(ConditionMessage.forCondition(MyConditional.class)
.because("match"));
} else {
return ConditionOutcome.noMatch(ConditionMessage.forCondition(MyConditional.class)
.because("not match"));
}
}
}
- 编写自定义注解
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyOnCondition.class)
public @interface MyConditional {
String value() default "";
}
- 应用注解到@Configuration 类或者@Bean 方法上
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.annotation.Configuration;
@MyConditional(value = "myCondition1")
@Configuration(proxyBeanMethods = false)
public class MyTomcatConnector implements TomcatConnectorCustomizer {
@Override
public void customize(Connector connector) {
connector.setPort(9091);
System.out.println("connector设置为9091");
}
}
总结
基于SpringBoot 实现自定义注解很方便,我们可以针对公司业务定制自己的条件注解,从实现外部化配置调整应用行为。