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); }