写点什么

【源码系列】Spring Boot 条件配置

用户头像
Alex🐒
关注
发布于: 2021 年 06 月 09 日

条件注解

@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;               }          }     }     // ...}
复制代码


发布于: 2021 年 06 月 09 日阅读数: 9
用户头像

Alex🐒

关注

还未添加个人签名 2020.04.30 加入

还未添加个人简介

评论

发布
暂无评论
【源码系列】Spring Boot 条件配置