Spring Boot自动配置原理

  上篇Spring Boot基本配置之入口类和@SpringBootApplication已经查看到了Spring Boot启动时自动装配了哪些内容,那么Spring Boot是如何知晓装配内容并在启动时自动加载的呢?答案尽在@SpringBootApplication注解。

  Spring Boot自动配置机制从核心上可以总结为以下两点:

    1、通过@EnableAutoConfiguration为基于Spring的应用开启自动配置机制;

    2、通过一系列的@Conditional完成自动配置机制的实现,关于Spring的条件注解可参考Spring Boot 热插拔技术应用 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)

  如何理解自动配置?自动配置即根据开发者添加的jar包依赖,会自动将一些配置类的bean注册到ioc容器内。使用时只需方便的添加@Autowire或者@Resource等注解即可使用。

  通过源码可知其为组合注解

              

   @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解各个分析:

  一、@SpringBootConfiguration

              

   通过源码分析:@SpringBootConfiguration等价于@Configuration,其为@Configuration的重新封装命名同时默认使用代理bean方法。

  二、@EnableAutoConfiguration

              

     对于此注解,标记可覆盖属性为“spring.boot.enableautoconfiguration”,同时与如下两注解作用:

    1、@AutoConfigurationPackage

              

      @Import这个注解,使用Spring经常可见,其为spring底层注解,表示给容器中导入一个组件。此处导入的组件是Registrar.class。那Registrar组件的功能是什么呢?查看源码如下:

        

       通过Registrar源码,可知其主要干一件事,注册一个bean。那么这个bean是什么呢?我们跟踪调试查看下:

        

       这个bean就是

        

      其中的packageNames为,即main主函数所在包。

    综合此注解功能就是自动装配main主函数所在package中所有bean。

    2、@Import({AutoConfigurationImportSelector.class})

      此处导入容器的组件是AutoConfigurationImportSelector.class,关于这个enable注解的原理可参考Spring高级特性之三:@Enable*注解的工作原理

,其UML图如下:

        

    对于*Aware相关的接口,其为Spring提供的Bean与Spring框架耦合的契机。简单说就是Spring的一个亮点就是开发者使用Bean对Spring容器的存在是没有意识的,可以将使用的容器替换成其他的容器。但实际应用中有时不可避免的要用到Spring容器本身的功能资源,这个时候Bean必须意识其所在容器的存在才能调用Spring提供的而相关资源。这个功能可以通过Spring Aware。具体可参考Spring高级特性之一: Aware之ApplicationContextAware

    AutoConfiurationImportSelector类实现了图中的相关Aware,重点是此类实现了DeferredImportSelector接口的getImportGroup()方法:

        

     下面分析自动装配的主要逻辑process的功能:

        

     依次跟踪调试可以发现EnableAutoConfigurationImportSelector使用SpringFactoriesLoader:loadFactoryNames方法扫描spring.factorires文件

        

    此文件声明哪些需要自动配置。打开该文件

        

     打开上面任意配置文件,如:

        

     可以明确看到很多@ConditionalXXX相关的条件注解:

        

  其实这个实现逻辑可以参考Dubbo SPI机制之一JDK中的SPI进行对比。以上的自动装配都是Spring Boot嵌入的,下面以http编码为例简析一个自定义的配置如何自动装配:

  常规项目配置http编码实在web.xml文件中配置一个filter避免中文乱码,如:

          

  如果将上述过程改为自动装配,那必须满足两个条件:

    1)能配置CharacterEncodingFilter这个Bean;

    2)能配置encoding和forceEncoding这两个参数。

    首先,关于配置参数。之前分析过类型安全配置(参考Spring Boot外部配置属性注入),Spring Boot参数配置基于此实现。这个配置类可以在application.properties中直接设置,如下:

          

    那么参数对应源码应该是

          

     对于其他可在application.properties中设置参数的选项,其参数配置源码,应该都是类似的XXXProperties并包含注@ConfigurationProperties("XXX")。

    其次,对于注册Bean,通过源码解析:

          

     通过上述实例的分析,可以总结springboot配置的大致逻辑如下:

          

  三、@ComponentScan

    这个是Spring提供的基本注解,可参考Spring相关注解文章。

  总而言之

    根据不同的条件判断,决定这个配置类是否生效。一旦这个配置类生效,这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这个类里面的每个属性又是与配置文件绑定的。所有在配置文件中的配置属性都是在XXXProperties类中封装着,配置文件怎么配置属性可以参考对应的类属性。

  精髓就是:

    1、SpringBoot启动时会加载大量的自动配置列;

    2、实际开发中需要实现的功能有没有SpringBoot默认写好的配置类;

    3、如果有再看这个自动配置类中到底配置类哪些组件;(只要有需要的,即无需在进行配置了)

      xxxAutoConfiguration:自动配置类,用于给容器中添加组件从而代替之前手动完成大量繁琐配置。

    4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。这样开发者可以在配置文件中指定这些属性的值。

      xxxProperties:封装了对应自动配置类的默认属性值,如果需要自定义属性值,只要根据该类寻找相关属性在配置文件设置即可。

  

   

posted on 2021-04-25 20:04  池塘里洗澡的鸭子  阅读(2977)  评论(0编辑  收藏  举报