栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot自动配置原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot自动配置原理

前言

SpringBoot帮我们把一切都做好了,让我们只关注业务逻辑的开发,让我们对原理一探究竟。

@SpringBootApplication注解

Spring的一切自动配置起源于主程序的SpringBootApplication注解,进入SpringBootApplication注解可以看到, 他是由三个注解组合而成的。

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
@SpringBootConfiguration

 用@Configuration注解标注, 就表示SpringBootConfiguration是一个配置类(Springboot的核心配置类),就说明了我们创建的Springboot应用的主程序类也是一个配置类,

@ComponentScan

指定包的扫描,腰扫描那些包。

@EnableAutoConfiguration (核心重点)

由两个个注解组合而成       

@AutoConfigurationPackage
@import({AutoConfigurationimportSelector.class})

@AutoConfigurationPackage  

进入@AutoConfigurationPackage 可以看到这个类上面标注了一个@import({Registrar.class})  注解, 表示给容器导入一个组件  

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

    Class[] basePackageClasses() default {};
}

我们进入@import({Registrar.class})的Registrar.class类看一下,到底要导入什么组件。

  • 利用Registrar给容器中导入一系列组件
  • 将指定的一个包下的所有组件导入进来?MainApplication 所在包下。

Registrar类中有两个方法, 第一个方法就是批量注册组建的,这里的参数metadata就是标注该注解的类,最终也就是我们创建的SpringBoot应用程序的主程序启动类。


AutoConfigurationPackages.register方法中参数
(new AutoConfigurationPackages.Packageimports(metadata)).getPackageNames().toArray(new String[0]) 利用标注在主程序的类的元数据计算机出主程序所在的包名,创建一个数组然后注册到容器,这也就说明了为什么我们创建的Controller等要在主类包的下面。(register就是把某一个包下的所有组件批量注册进去)

 @import({AutoConfigurationimportSelector.class})

给容器中批量导入组件,导入那些组件呢?

进入AutoConfigurationimportSelector.class, 有一个selectimports方法,返回一个数组,返回哪些就是给容器中导入哪些组件。

 public String[] selectimports(Annotationmetadata annotationmetadata) {
        if (!this.isEnabled(annotationmetadata)) {
            return NO_importS;
        } else {
            AutoConfigurationimportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationmetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

selectimports方法中有一个getAutoConfigurationEntry方法, 所有的东西都是通过这个方法得到的,然后再autoConfigurationEntry.getConfigurations()得到配置返回。

我们看一下getAutoConfigurationEntry源码,List configurations = this.getCandidateConfigurations(annotationmetadata, attributes); 活得了134个类,这是全部要导入到容器里面的。

 我们再继续往下看,看看List configurations = this.getCandidateConfigurations(annotationmetadata, attributes) 是如何获取这134个组建的呢?一直从方法里面往下调,一直到SpringFactoriesLoader的loadSpringFactories方法。

从meta-INF/spring.factories位置来加载一个文件。 默认扫描我们当前系统里面所有meta-INF/spring.factories位置的文件 spring-boot-autoconfigure-2.3.4.RELEASE.jar(这是核心自动配置类)包里面也有meta-INF/spring.factories

文件里面写死了spring-boot一启动就要给容器中加载的所有配置类

 自动配置:

只有我们在pom.xml文件中引入了的组件才会生效, 因为每个XXXautoConfigure是通过@  注解进行条件装配的,如果我们在pom.xml文件中引入了相关依赖,那么这个依赖jar就会生效,通过@ConditionalOnBean({CacheAspectSupport.class})条件的判断来决定是否注入Bean,下图,如果容器中没有CacheManager,那么整个类里面的方法就不执行了,如果存在那么就注入。

 Web自动配置

  • DispatcherServletRegistrationConfiguration

全流程原理:主类上的@SpringBootApplication注解上的@EnableAutoConfiguration注解。

通过@EnableAutoConfiguration上的@import({AutoConfigurationimportSelector.class})

AutoConfigurationimportSelector中的selectimports方法一直往里调用,从meta-INF/spring.factories位置来加载一个文件。 默认扫描我们当前系统里面所有meta-INF/spring.factories位置的文件 spring-boot-autoconfigure-2.3.4.RELEASE.jar(这是核心自动配置类)包里面也有meta-INF/spring.factories, 加载134个组件。再通过pom.xml文件中的导入的依赖场景按需加载。(其他如字符解析器,视图解析器都是这样注入的)

因为默认导入了spring-boot-starter-web场景, 那么web/servlet的依赖都会被导入DispatcherServletRegistrationConfiguration就是SpringMVC的前端控制器的自动配置。

WebMvcProperties的属性通过配置文件设置给dispatcherServlet实例

@EnableConfigurationProperties({WebMvcProperties.class})这个注解主要用来把配置文件的值绑定到WebMvcProperties这个类上并注入到容器

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

  • 底层配置的原理就是通过@ConditionalOnBean({XXX.class})条件的判断来决定是否注入Bean,注入的,如果我们要自定义配置,可以按照这种方式
 @Bean
    @ConditionalOnMissingBean({MultipartConfigElement.class, CommonsMultipartResolver.class})
    public MultipartConfigElement multipartConfigElement() {
        return this.multipartProperties.createMultipartConfig();
    }
@Bean
  @ConditionalOnMissingBean
  public CharacterEncodingFilter characterEncodingFilter() {
    }

总结:
  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置

           用户直接自己@Bean替换底层的组件

           用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344988.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号