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 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 {

    ....

}

 

  1.        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.重点看一下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.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);

        }

}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FantasyBaby

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值