前言
本文我们来解析OnEnabledEndpointCondition的实现,这个还是很简单的.目的是为了做下缓冲,后面的内容比较复杂.好了,开始吧.
解析
@ConditionalOnEnabledEndpoint
代码如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@Conditional(OnEnabledEndpointCondition.class)
@Documented
public @interface ConditionalOnEnabledEndpoint {
// endpoint的名字
String value();
// 返回endpoint是否可用,默认是可用的
boolean enabledByDefault() default true;
}
其处理类为OnEnabledEndpointCondition.
OnEnabledEndpointCondition
OnEnabledEndpointCondition 继承自SpringBootCondition.
getMatchOutcome 实现如下:
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { // 1. 获得@ConditionalOnEnabledEndpoint配置的Endpoint的名字和enabledByDefault的值 AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(metadata .getAnnotationAttributes(ConditionalOnEnabledEndpoint.class.getName())); String endpointName = annotationAttributes.getString("value"); boolean enabledByDefault = annotationAttributes.getBoolean("enabledByDefault"); // 2. 获得endpoints.endpointName.enabled 的配置.然后进行返回,如此时传入的是env,则读取endpoints.env.enabled 的配置 ConditionOutcome outcome = determineEndpointOutcome(endpointName, enabledByDefault, context); if (outcome != null) { return outcome; } // 3.读取endpoints.enabled的配置,如果没有配置的话,则默认匹配 return determineAllEndpointsOutcome(context); }
- 获得@ConditionalOnEnabledEndpoint配置的Endpoint的名字和enabledByDefault的值
获得endpoints.endpointName.enabled 的配置.如果有配置的化则进行返回.如此时传入的是env,则读取endpoints.env.enabled 的配置.代码如下:
private ConditionOutcome determineEndpointOutcome(String endpointName, boolean enabledByDefault, ConditionContext context) { RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( context.getEnvironment(), "endpoints." + endpointName + "."); if (resolver.containsProperty("enabled") || !enabledByDefault) { boolean match = resolver.getProperty("enabled", Boolean.class, enabledByDefault); ConditionMessage message = ConditionMessage .forCondition(ConditionalOnEnabledEndpoint.class, "(" + endpointName + ")") .because(match ? "enabled" : "disabled"); return new ConditionOutcome(match, message); } return null; }
- 实例化RelaxedPropertyResolver,读取endpoints.endpointName. 开头的配置
如果配置有endpoints.endpointName.enabled 或者 默认该endpoint不默认生效
- 获得有endpoints.endpointName.enabled的值,构造ConditionOutcome,然后返回
- 返回null
读取endpoints.enabled的配置,如果没有配置的话,则默认匹配.代码如下:
private ConditionOutcome determineAllEndpointsOutcome(ConditionContext context) { RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( context.getEnvironment(), "endpoints."); boolean match = Boolean.valueOf(resolver.getProperty("enabled", "true")); ConditionMessage message = ConditionMessage .forCondition(ConditionalOnEnabledEndpoint.class) .because("All endpoints are " + (match ? "enabled" : "disabled") + " by default"); return new ConditionOutcome(match, message); }
- 实例化RelaxedPropertyResolver,读取endpoints. 开头的配置
- 获取endpoints.enabled 的配置,如果没有配置,则返回true
- 构造ConditionOutcome进行返回
使用案例:
在EndpointWebMvcManagementContextConfiguration中有如下方法:
@Bean @ConditionalOnMissingBean @ConditionalOnBean(EnvironmentEndpoint.class) @ConditionalOnEnabledEndpoint("env") public EnvironmentMvcEndpoint environmentMvcEndpoint(EnvironmentEndpoint delegate) { return new EnvironmentMvcEndpoint(delegate); }
其中使用到了@ConditionalOnEnabledEndpoint注解,意思是当配置有endpoints. env.enabled=true或者配置有endpoints.enabled=true或者没有配置endpoints.enabled,endpoints. env.enabled时默认生效