Spring boot autoconfiguration原理

1.自动装配扫描实例

@EnableAutoConfiguration 引入了 @AutoConfigurationPackage

最终引入了 AutoConfigurationPackages

 

register方法 通过BeanDefinitionRegistry 和 包名 来扫描实例,所以默认的情况下不需要不使用@CompomnentScan也会扫描当前注解所在包以及包下面的子包.

2自动装配选择加载实例

2.1调用到selector的方法流程

根据上面时序图可以看出 框架在AutoConfigurationGroup直接调用了getAutoConfigurationEntry()

  •      groupprocess方法

    1

    2

    3

    4

    5

    6

    7

    8

    9

public voidprocess(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

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

        //排序后返回迭代对象

        returnsortAutoConfigurations(processedConfigurations,getAutoConfigurationMetadata()).stream()

                        .map((importClassName) ->newEntry(this.entries.get(importClassName), importClassName))

                        .collect(Collectors.toList());

}

2.2AutoConfigurationImportSelector

    该类继承

1.@EnableAutoConfiguration 注解引入了AutoConfigurationImportSelector

    1

    2

    3

    4

@Import(AutoConfigurationImportSelector.class)

public@interfaceEnableAutoConfiguration {

    ....

}

 

  1.        selectImports()方法该方法在新版本没有被调用(使用版本springboot 2.1.3)

    1

    2

    3

    4

    5

    6

    7

publicString[]selectImports(AnnotationMetadata annotationMetadata) {

    if(!isEnabled(annotationMetadata)) {

        returnNO_IMPORTS;

    }

    AutoConfigurationEntry autoConfigurationEntry =getAutoConfigurationEntry(annotationMetadata);

    returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations());

}

2.重点看一下AutoConfigurationImportSelectorgetAutoConfigurationEntry()

通过

   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.2ConfigurationClasBeanDefinitionReader

    其中通过 AutoConfigurationPackages.Registrar registerBeanDefinitions()

     注册相应的bean

    1

    2

    3

    4

    5

    6

public voidloadBeanDefinitions(Set<ConfigurationClass> configurationModel) {

        TrackedConditionEvaluator trackedConditionEvaluator =newTrackedConditionEvaluator();

        for(ConfigurationClass configClass : configurationModel) {

                loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);

        }

}


版权声明:本文为FantasyBaby原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。