SpringBoot源码下载地址:https://github.com/spring-projects/spring-boot/tags
🍟下载源码
我们下载2.2.9.RELEASE版本,2.3.0以上版本需要用gradle构建
解压完之后运行maven安装命令
mvn clean install -DskipTests
🍗环境准备
在springboot源码项目下创建一个新的模块,这样方便我们debug源码

🍖注解解析
点进去我们可以看到一共有七个注解
🍝@SpringBootConfiguration注解

它的作用就是标识springboot启动类为bean
🍛@EnableAutoConfiguration注解

该注解是启动自动装配的功能,这就是springboot能自动装配的核心
🍤@AutoConfigurationPackage注解

@Import注解是spring中的注解,这里不再赘述他的作用,这里面导入了一个AutoConfigurationPackages.Registrar.class
Registrar静态内部类

register方法

所以AutoConfigurationPackage注解的目的是将BasePackages类注册进ioc中
再回到@EnableAutoConfiguration注解的import注解中

AutoConfigurationImportSelector类

他实现了很多的Aware接口,Aware接口的作用就是回调函数,他在spring运行的过程中会调用他的接口方法并且将入参赋值给子类的成员变量

我们进入到该类的process方法中
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process
在执行的过程中会回调改方法

进入完成装配的方法getAutoConfigurationEntry
org.springframework.boot.autoconfigure.EnableAutoConfiguration,待会要拿的key值

要取的文件

所以getAutoConfigurationEntry方法里面的getCandidateConfigurations方法获取了META-INF/spring.factories
文件中的key(org.springframework.boot.autoconfigure.EnableAutoConfiguration)值

我们去看看所有key是META-INF/spring.factories
文件


这些全限定类名就是自动装配的关键

我们不可能把124个bean注册到ioc中,所以我们经过一系列的过滤得到了最终的23个bean 而去除这些bean的关键就是下面这段代码
//去除不需要注册的bean
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
其中最重要的方法是filter方法

我们举个例子,去看一下RabbitAutoConfiguration类


@ConditionalOnClass注解中没有满足classpath目录(pom文件导入jar)下有RabbitTemplate.class
, Channel.class
类的即不装配 还有很多内置spring的@Conditional注解的springboot注解
关于条件注解的讲解 @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。 ·@ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。 ·@ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。 ·@ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。基于SpEL表达式的条件判断。 ·@ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。 ·@ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
剩下createBean就交给spring去处理就好了
@EnableAutoConfiguration注解已经讲完了
🍱@ComponentScan注解
·basePackages、value:指定扫描路径,如果为空则以@ComponentScan注解的类所在的包为基本的扫描路径 ·basePackageClasses:指定具体扫描的类 ·incIudeFiIters:指定满足FiIter条件的类 ·excludeFilters:指定排除FiIter条件的类
因为@ComponentScan注解没有basePackages、value属性,所以springboot会默认扫描启动类所在的包
🍣所以这篇博客解决了标题的问题
🍥@SpringBootApplication注解的作用是什么?
-
@SpringBootConfiguration注明该类为配置类 -
@EnableAutoConfiguration完成自动装配 -
@ComponentScan完成扫描路径
🍙SpringBoot怎么实现自动装配的?
-
通过 @EnableAutoConfiguration注解找到所有的 META-INF/spring.factories
文件 -
拿到key为 org.springframework.boot.autoconfigure.EnableAutoConfiguration
的value -
去除掉不符合条件的bean,满足@Conditional注解等信息的bean才会注册 -
在run方法中注册符合条件的bean,run方法会扫描@SpringBootApplication里面的信息,从而注册进入ioc (重要,因为run方法才能使@SpringBootApplication注解生效)
得到了一个规律:
几乎所有自动配置类都叫xxxAutoConfiguration

而在yaml或者properties文件中配置的key都是xxxProperties


原文始发于微信公众号(掉头发的王富贵):【SpringBoot】@SpringBootApplication注解的作用是什么?SpringBoot怎么实现自动装配的?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/315736.html