欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot自动配置原理

程序员文章站 2022-07-10 11:31:32
前言 只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star: "https://github.com/ZhongFuCheng3y/3y" 回顾前面Spring的文章(以学习的顺序排好): "Spring入门这一篇就够了" "Spring【依赖注入】就是这么简单" "Spring【AO ......

前言

只有光头才能变强。

文本已收录至我的github仓库,欢迎star:https://github.com/zhongfucheng3y/3y

回顾前面spring的文章(以学习的顺序排好):

作为一名java程序员,就不可能不了解springboot,如果不了解(赶紧学!)

一、springboot的自动配置原理

不知道大家第一次搭springboot环境的时候,有没有觉得非常简单。无须各种的配置文件,无须各种繁杂的pom坐标,一个main方法,就能run起来了。与其他框架整合也贼方便,使用enablexxxxx注解就可以搞起来了!

所以今天来讲讲springboot是如何实现自动配置的~

1.1三个重要的注解

我们可以发现,在使用main()启动springboot的时候,只有一个注解@springbootapplication

SpringBoot自动配置原理

我们可以点击进去@springbootapplication注解中看看,可以发现有三个注解是比较重要的:

SpringBoot自动配置原理

  • @springbootconfiguration:我们点进去以后可以发现底层是configuration注解,说白了就是支持javaconfig的方式来进行配置(使用configuration配置类等同于xml文件)。
  • @enableautoconfiguration:开启自动配置功能(后文详解)
  • @componentscan:这个注解,学过spring的同学应该对它不会陌生,就是扫描注解,默认是扫描当前类下的package。将@controller/@service/@component/@repository等注解加载到ioc容器中。

所以,java3yapplication类可以被我们当做是这样的:

@springbootconfiguration
@enableautoconfiguration
@componentscan
public class java3yapplication {

    public static void main(string[] args) {
        springapplication.run(java3yapplication.class, args);
    }
}

1.2重点enableautoconfiguration

我们知道springboot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那springboot是怎么做的呢?其实靠的就是@enableautoconfiguration注解。

简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置

介绍有一句说:

if you have tomcat-embedded.jar on your classpath you are likely to want a tomcatservletwebserverfactory

如果你的类路径下有tomcat-embedded.jar包,那么你很可能就需要tomcatservletwebserverfactory

我们点进去看一下,发现有两个比较重要的注解:

SpringBoot自动配置原理

  • @autoconfigurationpackage:自动配置包
  • @import:给ioc容器导入组件

1.2.1autoconfigurationpackage

网上将这个@autoconfigurationpackage注解解释成自动配置包,我们也看看@autoconfigurationpackage里边有什么:

SpringBoot自动配置原理

我们可以发现,依靠的还是@import注解,再点进去查看,我们发现重要的就是以下的代码:

@override
public void registerbeandefinitions(annotationmetadata metadata,
        beandefinitionregistry registry) {
    register(registry, new packageimport(metadata).getpackagename());
}

默认的情况下就是将:主配置类(@springbootapplication)的所在包及其子包里边的组件扫描到spring容器中。

  • 看完这句话,会不会觉得,这不就是componentscan的功能吗?这俩不就重复了吗?

我开始也有这个疑问,直到我看到文档的这句话:

it will be used when scanning for code @entity classes.
it is generally recommended that you place enableautoconfiguration (if you're
not using @springbootapplication) in a root package so that all sub-packages
and classes can be searched.

比如说,你用了spring data jpa,可能会在实体类上写@entity注解。这个@entity注解由@autoconfigurationpackage扫描并加载,而我们平时开发用的@controller/@service/@component/@repository这些注解是由componentscan来扫描并加载的。

  • 简单理解:这二者扫描的对象是不一样的。

1.2.2回到import

我们回到@import(autoconfigurationimportselector.class)这句代码上,再点进去autoconfigurationimportselector.class看看具体的实现是什么:

SpringBoot自动配置原理

我们再进去看一下这些配置信息是从哪里来的(进去getcandidateconfigurations方法):

SpringBoot自动配置原理

这里包装了一层,我们看到的只是通过springfactoriesloader来加载,还没看到关键信息,继续进去:

SpringBoot自动配置原理

简单梳理:

  • factories_resource_location的值是meta-inf/spring.factories
  • spring启动的时候会扫描所有jar路径下的meta-inf/spring.factories,将其文件包装成properties对象
  • 从properties对象获取到key值为enableautoconfiguration的数据,然后添加到容器里边。

SpringBoot自动配置原理

最后我们会默认加载113个默认的配置类:

SpringBoot自动配置原理

有兴趣的同学可以去翻一下这些文件以及配置类哦:

SpringBoot自动配置原理

1.3总结

@springbootapplication等同于下面三个注解:

  • @springbootconfiguration
  • @enableautoconfiguration
  • @componentscan

其中@enableautoconfiguration是关键(启用自动配置),内部实际上就去加载meta-inf/spring.factories文件的信息,然后筛选出以enableautoconfiguration为key的数据,加载到ioc容器中,实现自动配置功能!

SpringBoot自动配置原理

官网文档参考:

英语不好的同学可以像我一样,对照着来看:

SpringBoot自动配置原理

最后

乐于输出干货的java技术公众号:java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

SpringBoot自动配置原理

觉得我的文章写得不错,不妨点一下