前言

只有光头才能变强。

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

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

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

一、SpringBoot的自动配置原理

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

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

1.1三个重要的注解

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

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

  • @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

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

  • @AutoConfigurationPackage:自动配置包
  • @Import:给IOC容器导入组件

1.2.1AutoConfigurationPackage

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

我们可以发现,依靠的还是@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看看具体的实现是什么:

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

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

简单梳理:

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

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

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

1.3总结

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

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

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

官网文档参考:

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

最后

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

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

SpringBoot自动配置原理的更多相关文章

  1. 这样讲 SpringBoot 自动配置原理,你应该能明白了吧

    https://juejin.im/post/5ce5effb6fb9a07f0b039a14 前言 小伙伴们是否想起曾经被 SSM 整合支配的恐惧?相信很多小伙伴都是有过这样的经历的,一大堆配置问题 ...

  2. springboot自动配置原理以及手动实现配置类

    springboot自动配置原理以及手动实现配置类 1.原理 spring有一个思想是"约定大于配置". 配置类自动配置可以帮助开发人员更加专注于业务逻辑开发,springboot ...

  3. SpringBoot实战之SpringBoot自动配置原理

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  4. 3. SpringBoot ——自动配置原理浅析

    SpringBoot的功能之所以强大,离不开它的自动配置这一大特色.但估计很多人只是知其然而不知其所以然.下面本人对自动配置原理做一个分析: 在使用SpringBoot时我们通过引入不同的Starte ...

  5. SpringBoot自动配置原理学习

    介绍 构建Springboot项目时我们会创建一个启动类 @SpringBootApplication public class DemoApplication { public static voi ...

  6. 浅谈springboot自动配置原理

    前言 springboot自动配置关键在于@SpringBootApplication注解,启动类之所以作为项目启动的入口,也是因为该注解,下面浅谈下这个注解的作用和实现原理 @SpringBootA ...

  7. SpringBoot系列二:SpringBoot自动配置原理

    主程序类的注解 @SpringBootApplication 注解,它其实是个组合注解,源码如下: @Target({ElementType.TYPE}) @Retention(RetentionPo ...

  8. springBoot 自动配置原理--自己新建一个 starter

    上篇我们说到 springboot 和 SSM 框架的区别,今天我们就看看 springboot 到底为我们做了哪些事情,让我们开发变得如此简单. springboot 中起着重要作用的是 start ...

  9. springBoot 自动配置原理

    在之前文章中说过,springBoot会根据jar包去添加许多的自动配置,本文就来说说为什么会自动配置,自动配置的原理时什么? springBoot在运行SpringApplication对象实例化时 ...

随机推荐

  1. Flex 右键菜单控制

    //设置监控右键菜单项 private function setUserMenuItem():void{ var contextMenu:ContextMenu = new ContextMenu() ...

  2. Java多线程:wait(),notify(),notifyAll()

    1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...

  3. lambda函数常见用法

    # lambda 参数:返回值/表达式 # print((lambda :100)()) # f = lambda a,b : a + b # print(f(10, 20)) # f = lambd ...

  4. Python_shelve模块操作二进制文件

    import shelve #导入shelve模块 fp=shelve.open('shelve_test.dat') #创建或打开二进制文件 zhangsan={'age':38,'sex':'Ma ...

  5. The JRE_HOME environment variable is not defined correctly

    启动Tomcat后startup.bat脚本调用了catalina.bat,然后catalina.bat调用了setclasspath.bat,setclasspath.bat的头部定义了JAVA_H ...

  6. activemq+Zookeper高可用集群方案配置

    在高并发.对稳定性要求极高的系统中,高可用的是必不可少的,当然ActiveMQ也有自己的集群方案.从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式 ...

  7. Linux获取网络接口信息

    linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf 1.ioctl()函数原型及作用 #include <sys/ioctl.h ...

  8. C++之Binary Heap/Max Heap

    #include <iostream> #include <time.h> #include <random> using namespace std; //Bin ...

  9. mysql管理工具navicat的快捷键

    1. ctrl + q  或者 ctrl+n: 打开新查询窗口 2. ctrl + r: 运行当前窗口内的所有语句 3. ctrl + shit + r: 只运行选中的语句 4. ctrl + w: ...

  10. Vim手册

    什么是 vim? Vim是从 vi 发展出来的一个文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用. 简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是 ...