条件注解
@Conditional
参数是 Condition 数组
@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Conditional { Class<? extends Condition>[] value();}
复制代码
Condition
提供 matches 方法,符合配置条件的返回 true
@FunctionalInterfacepublic interface Condition { boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}
复制代码
实现一个自定义条件注解
@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.TYPE, ElementType.METHOD })@Documented@Conditional(OnXXXXXCondition.class)public @interface ConditionalOnXXXXX {}
public OnXXXXXCondition implements Conditional { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // TODO }}
复制代码
Springboot 提供的常用条件注解(org.springframework.boot.autoconfigure.condition)
批量条件配置
Spring boot 提供了 spring-autoconfigure-metadata.properties 文件来实现批量自动装配条件配置,可以更有效的降低启动时间,原理是类似的
META-INF/spring-autoconfigure-metadata.properties 内容格式:自动配置类的全路径.条件=值
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.ConditionalOnClass=\ org.influxdb.InfluxDB org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration.AutoConfigureAfter=\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration org.springframework.boot.autoconfigure.session.RedisSessionConfiguration.ConditionalOnClass=\ org.springframework.data.redis.core.RedisTemplate,org.springframework.session.data.redis.RedisOperationsSessionRepository
复制代码
自动装配的代码
// 加载 META-INF/spring-autoconfigure-metadata.properties 文件 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry( autoConfigurationMetadata, annotationMetadata);
复制代码
protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { // ... configurations = filter(configurations, autoConfigurationMetadata); // ..}
复制代码
private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) { String[] candidates = StringUtils.toStringArray(configurations); boolean[] skip = new boolean[candidates.length]; boolean skipped = false; // AutoConfigurationImportFilter 执行 filter // 实现类: // OnBeanCondition // OnClassCondition // OnWebApplicationCondition for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) { invokeAwareMethods(filter); boolean[] match = filter.match(candidates, autoConfigurationMetadata); for (int i = 0; i < match.length; i++) { if (!match[i]) { skip[i] = true; candidates[i] = null; skipped = true; } } } // ...}
复制代码
评论