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

SpringBoot源码解析

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

SpringBoot源码解析

目录

SpringBoot自动配置原理

  1、@SpringBootConfiguration

  2、@ComponentScan

  3、@EnableAutoConfiguration(关键)

     1)进入@AutoConfigurationPackage

      2)进入@import(AutoConfigurationimportSelector.class)注解

  4、按需配置

  5、修改默认配置

  总结


SpringBoot自动配置原理

  主类上的注解@SpringBootApplication,ctrl+单击进入可知,相当于重点的几个注解组合

    ①.@SpringBootConfiguration

    ②.@EnableAutoConfiguration

    ③.@ComponentScan(.....)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  1、@SpringBootConfiguration

    --> 就相当于是标志为这是一个配置类,等价于@Configuration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Configuration
public @interface SpringBootConfiguration {

  2、@ComponentScan

    --> 由该注解中的excludeFilters、@Filter等字眼看出就是指定扫描哪Spring注解的

  3、@EnableAutoConfiguration(关键)

     进入该注解可以看到有@AutoConfigurationPackage和@import(AutoCo....)两个关键注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@AutoConfigurationPackage
@import(AutoConfigurationimportSelector.class)
public @interface EnableAutoConfiguration {

     1)进入@AutoConfigurationPackage

        --> 有个关键注解:@import(AutoConfigurationPackages.Registrar.class),给容器导入组件

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@import(AutoConfigurationPackages.Registrar.class)   //给容器中导入一个组件
public @interface AutoConfigurationPackage {

          --> 查看import导入的配置类Registrar到底注册什么,ctrl单机进入Registrar,大致就是利用Registrar给容器中导入一系列组件(由最后的toArray()可知,将指定的一个包下的所有组件导入进来)

      2)进入@import(AutoConfigurationimportSelector.class)注解

        --> 看源码中 selectimports 方法,查看选择导入规则

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

       --> 重点分析getAutoConfigurationEntry(annotationmetadata)方法给容器中批量导入一些组件

       --> 可以看出先拿到需要导入容器的配置类信息 configurations,然后就是对该配置类信息进行一些了筛选:removeDuplicates(去重)、chekExclude..(排除)、filter...等进行筛选过滤

       -->所以重点方法:List configurations = getCandidateConfigurations(annotation...),该方法获取到所有需要导入到容器中的配置类

        -->可以看到,可获取到127个相关配置类(后面会解释这个127个来源:spring.factories)

        --> debug进入getCandidateConfigurations候选配置类方法,分析该方法是如何获取所需要导入容器中的配置类的

        -->①.查看loadFactoryNames方法,可以看出由spring的工厂加载器来加载一些东西的,所以再进入loadFactoryNames进行查看

protected List getCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) {
		List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in meta-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

        -->②.显然还要进而再进入loadFactoryNames方法中的loadSpringFactories查看

public static List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader) {
        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

         -->③.最终关键利用工厂加载 Map> loadSpringFactories(@Nullable ClassLoader classLoader)得到所有的组件

         -->结论:默认扫描我们当前系统里面所有 meta-INF/spring.factories 位置的文件

         -->spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有meta-INF/spring.factories

         -->文件里写死了spring-boot一启动就给容器中加载的所有配置类(auto Configure:127个)

  4、按需配置

    虽然有127个场景的所有自动配置启动的时候默认全部加载。xxxAutoConfiguration

    但是都是由相关注解(@Conditional),安装条件装配规则,最终按需配置的,如图

  5、修改默认配置

    底层运用了@ConditionalOnBean、@ConditionalOnMissingBean、@Conditional等注解进行条件配置,即默认底层配好所有相应场景地组件的同时,还允许优先使用用户自己配置的

    下面看一下底层为我们配好的一些组件

    --> 关于springmvc的配置: 即不用像ssm整合那样些一堆配置信息于xml,web.xml中配置dispatcherservlet之类的了,如下图:

 

     -->文件解析器自动配置:联用了@ConditionalOnBean和@ConditionalOnMissingBean两个注解进行规范,即存在文件解析器MutipartResolver才生效(但是也要求用户没有定义相关名为multipartResolver的组件,避免发生冲突)

     -->字符编码自动配置:也用到了注解@ConditionalOnMissingBean,只要用户有自己的配置,就以用户的优先

  总结
  • SpringBoot先加载所有的自动配置类 xxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值(条件以@Conditional等注解进行限定,配置以xxxProperties里面拿,而xxxProperties和配置文件进行了绑定)
  • 生效的配置类会给容器中装配很多组件(@Bean)
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置

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

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

      如:xxxAutoConfiguration --> 导入许多组件 --> 组件从xxxProperties里面拿值 -->properties跟 application.properties进行了绑定

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

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

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