ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot2的自动配置原理

2021-12-24 16:00:19  阅读:167  来源: 互联网

标签:spring 配置 自动 注解 组件 原理 SpringBoot2 configurations


       今天学习了SpringBoot2的自动配置原理,认为十分巧妙,所以记录一下自己的学习感悟。

1 预备知识

        在介绍SpringBoot2的自动装配原理之前,有几个注解需要我们认识一下,这几个注解在我看来是自动装配原理的基础。

       1.1 @Conditional 条件装配

        这里的注解并不只有@Conditional,而是和@Conditional具有相同功能的注解,比如以下注解:

         此类注解的作用是:当满足Conditional指定的条件时,才进行组件的注入。

       1.2 @Import

         向容器中导入指定类型的组件

2 自动配置原理

       2.1 自动加载配置类

          进入SpringBoot2的启动类可以看到三个比较重要的注解,如下:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
)

          其中,@SpringBootConfiguration标注这是一个配置类,@ComPonentScan即要扫描那些包。这三个中最重要的即是@EnableAutoConfiguration注解。源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
====以下较为重要======
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {

        @AutoConfigurationPackager

          重要部分源码如下:

@Import({Registrar.class})
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
}

        其中@Import({Registrar.class})给容器中导入Registrar类型的组件。

        进入Register中可以看到以下方法

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }

        其中new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames()作用是得到主类的包名,然后将其封装到一个数组中,之后register扫描此包下所有符合条件的组件,再注册进容器中。

        所以说@AutoConfigurationPackager注解,作用是将指定的一个包下的组件导入容器中,默认为启动类所在的包下,这也说明了在没有修改相关配置时,我们要将其他组件写在启动类的目录下。

       @Import({AutoConfigurationImportSelector.class})

        此注解导入了AutoConfigurationImportSelector类型的组件,进入AutoConfigurationImportSelector代码中可以看到下面的方法:

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

                在List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes)打断点可以得到:

              由此可见,此方法是用来获取需要导入到容器的组件。再进入此方法可以得到最关键的方法,名为loadSpringFactories,源码太多,就不全部贴了。我们可以在loadSpringFactories的源码中看到此语句Enumeration urls = classLoader.getResources("META-INF/spring.factories")  目的是加载META-INF/spring.factories文件,默认扫描我们当前系统中所有META-INF/spring.factories文件。

               且spring-boot-autoconfigure-2.6.1.jar包中也有META-INF/spring.factories,此文件中写死了SpringBoot一启动就要给容器中加载的所有配置类,

          2.2 按需开启自动配置项

               上面说了META-INF/spring.factories文件中的所有场景的自动配置在启动的时候默认全部加载,但最终配置时并没有那么多,因为在配置时会按需配置,有些组件并不会配置。

              在SpringBoot2中,按需配置的解决方法主要是使用@Conditional及其有相同功能的注解

下面举个例子:
             
例如SpringBoot2中的Aop中使用了以下注解

    @ConditionalOnMissingClass({"org.aspectj.weaver.Advice"})

              即有Advice类才会把Aop放入容器中。

3 SpringBoot2的自动装配流程

             即启动时加载META-INF/spring.factories中所有的配置,但根据@Conditional及其有相同功能的注解使它们并不能全部生效,这样来保证按需装配。

这样来看,如果不被成千上万条源码吓到的话,SpringBoot2的自动装配原理挺简单的,加油。学习无止境。

标签:spring,配置,自动,注解,组件,原理,SpringBoot2,configurations
来源: https://blog.csdn.net/qq_52074153/article/details/122088567

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有