1.自动装配扫描实例
@EnableAutoConfiguration 引入了 @AutoConfigurationPackage
最终引入了 AutoConfigurationPackages
register方法 通过BeanDefinitionRegistry 和 包名 来扫描实例,所以默认的情况下不需要不使用@CompomnentScan也会扫描当前注解所在包以及包下面的子包.
2自动装配选择加载实例
2.1调用到selector的方法流程
根据上面时序图可以看出 框架在AutoConfigurationGroup直接调用了getAutoConfigurationEntry()
- group的process方法
1 2 3 4 5 6 7 8 9 | public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) { ... AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector) .getAutoConfigurationEntry(annotationMetadata); this.autoConfigurationEntries.add(autoConfigurationEntry); for (String importClassName : autoConfigurationEntry.getConfigurations()) { this.entries.putIfAbsent(importClassName, annotationMetadata); } } |
- 调用selectImports()返回排序后的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public Iterable<Entry> selectImports() { //把所有需要排除的转换成集合 Set<String> allExclusions = this.autoConfigurationEntries.stream() .map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet()); //把所有的Configurations转换成集合 Set<String> processedConfigurations = this.autoConfigurationEntries.stream() .map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream) .collect(Collectors.toCollection(LinkedHashSet::new)); //删除所有不需要的 processedConfigurations.removeAll(allExclusions); //排序后返回迭代对象 return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream() .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName)) .collect(Collectors.toList()); } |
2.2AutoConfigurationImportSelector
该类继承
1.@EnableAutoConfiguration 注解引入了AutoConfigurationImportSelector
1 2 3 4 | @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { .... }
|
-
selectImports()方法该方法在新版本没有被调用(使用版本springboot 2.1.3)
1 2 3 4 5 6 7 | public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } |
2.重点看一下AutoConfigurationImportSelector的getAutoConfigurationEntry()
通过
META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration
获取并且筛选出所有需要自动配置的类
2.3 注册自动配置类
2.3.1 ConfigurationClassParser
类中processImports方法会对所有的importsEntry 按顺序处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public void processGroupImports() { for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
grouping.getImports().forEach(entry -> { ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata()); try { //处理所有的imports类 processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter), Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)), exclusionFilter, false); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configurationClass.getMetadata().getClassName() + "]", ex); } }); } } |
2.3.2 ConfigurationClasBeanDefinitionReader
其中通过 AutoConfigurationPackages.Registrar registerBeanDefinitions()
注册相应的bean
1 2 3 4 5 6 | public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); for (ConfigurationClass configClass : configurationModel) { loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } } |