work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Spring Boot starter原理

Posted on 2020-03-08 20:32  work hard work smart  阅读(1205)  评论(0编辑  收藏  举报

Spring Boot starter原理

一、starter自动配置类导入

启动类上@SpringBootApplication -> 引入AutoConfigurationImportSelector -> ConfigurationClassParser 中处理 -> 获取spring.factories中EnableAutoConfiguration实现

 

1、进入AutoConfigurationImportSelector类的getAutoConfigurationEntry方法

 

 

2、然后进入getCandidateConfigurations类。

该方法作用是获得spring.factories当中实现EnableAutoConfiguration接口的类

 

 

3 获得所有实现了EnableAutoConfiguration的类

 

 

4、最终有WeacherAutoConfiguration

 

 

 

二、自动配置类的过滤

1、进入WeatherAutoConfiguration类

 

 2、进入ConditionalOnProperty注解

 

 

3、然后进入OnPropertyCondition类的getMatchOutcome方法。当metadata为com.exmaple.demo.WeatherAutoConfiguration时

遍历注解里的属性,增加到对应的math或者noMatch集合中。如果存在noMatch,则返回不匹配

 

 

4、进入determineOutcome方法

    private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) {
        OnPropertyCondition.Spec spec = new OnPropertyCondition.Spec(annotationAttributes);
        List<String> missingProperties = new ArrayList();
        List<String> nonMatchingProperties = new ArrayList();
        spec.collectProperties(resolver, missingProperties, nonMatchingProperties);
        return !missingProperties.isEmpty()?ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).didNotFind("property", "properties").items(Style.QUOTE, missingProperties)):(!nonMatchingProperties.isEmpty()?ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).found("different value in property", "different value in properties").items(Style.QUOTE, nonMatchingProperties)):ConditionOutcome.match(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).because("matched")));
    }

  

5、进入collectProperties方法

比较属性值是否匹配

        private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) {
            String[] var4 = this.names;
            int var5 = var4.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String name = var4[var6];
                String key = this.prefix + name;
                if(resolver.containsProperty(key)) {
                    if(!this.isMatch(resolver.getProperty(key), this.havingValue)) {
                        nonMatching.add(name);
                    }
                } else if(!this.matchIfMissing) {
                    missing.add(name);
                }
            }

        }

  最终通过equal判断是否匹配。

   private boolean isMatch(String value, String requiredValue) {
            return StringUtils.hasLength(requiredValue)?requiredValue.equalsIgnoreCase(value):!"false".equalsIgnoreCase(value);
        }