springboot自动装配原理

springboot自动装配原理

1.@SpringBootApplication注解

在springboot启动类中有一个==@SpringBootApplication==注解

image-20240418230951080

在Idea中,同时按住ctrl键和鼠标左键进入,会发现这是一个组合注解类

image-20240418231516092

点进==@SpringBootConfiguration注解后,发现里面有一个@Configuration==注解,由此可知启动类SpringbootApplication是一个配置类。

2.@EnableAutoConfiguration注解

回来再看这个==@EnableAutoConfiguration注解,会发现这也是一个组合注解类,但是里面有一个重要的注解@Import==,它引用了一个AutoConfigurationImportSelector.class类。

image-20240418233815800

3.selectImports方法

点进AutoConfigurationImportSelector.class会发现它实现了DeferredImportSelector接口,而DeferredImportSelector又继承了ImportSelectorimage-20240418234125464

image-20240418234050050

也就是说在AutoConfigurationImportSelector中重写了selectImports方法 ,果然我们往下翻找到了selectImports方法

image-20240418234831496


​ 值得一提的是,当前这个AutoConfigurationImportSelector类并没有直接实现ImportSelector接口,而是实现了DeferredImportSelector,SpringBoot对于DeferredImportSelector有另外一套流程,这一套流程并不会调用selectImports方法,

而这个流程非常复杂。虽然SpringBoot并不会直接调用这个方法,但是我们翻看源码来了解SpringBoot的自动装配流畅确实可以的。


可以看到这个selectImports方法返回类型为全类名数组,返回的是autoConfigurationEntry的getConfigurations方法,所以autoConfigurationEntry是一个重点,我们猜想上面一行的**getAutoConfigurationEntry()**方法需要知道这个自动装配的配置文件在哪里

4.自动装配配置文件

我们点进**getAutoConfigurationEntry()**方法,会看到它返回了一个new AutoConfigurationEntry(configurations, exclusions)对象

image-20240418235957952

很显然,这个对象中的configurations是有关配置的,而这个configurations是由getCandidateConfigurations(annotationMetadata, attributes)拿到的,所以我们进入这个getCandidateConfigurations

image-20240419000703995

它下面有一个断言:

No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.

意思就是说configurations不能为空,如果为空,就提示这个断言(在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.这个位置自动配置类没找到)

那么这个文件又在哪呢?

202404190026080.png

5.找到自动装配配置文件(.import文件)

我们打开项目的pom文件,找到起步依赖spring-boot-starter点进去,里面有一个spring-boot-autoconfigure的核心依赖

image-20240419003005542

从后面的autoconfigure就可以看出这是关于自动装配的

aMmwOiovk8TbUIG

image-20240419003704344

在这个文件中第142行可以知道DispatcherServletAutoConfiguration就在这个文件中,我们点进这个DispatcherServletAutoConfiguration

image-20240419212959421

会看到有一个注解AutoConfiguration,我们点进这个注解会看到里面里里面有一个==@Configuration==注解,说明其实这个DispatcherServletAutoConfiguration是一个配置类,但是使用AutoConfiguration有见名知意的好处

下面我们来重点来看==@ConditionalOnClass==注解,这个是注册Bean的条件注解,@ConditionalOnClass({DispatcherServlet.class})的意思就是:如果当前环境中有DispatcherServlet这个类,就去注册DispatcherServletAutoConfiguration这个Bean

BTM8hU4skvYuLGd

在这个DispatcherServletAutoConfiguration类中,有一个内部类DispatcherServletConfiguration

从@Configuration注解可以知道这是一个配置类,下面在dispatcherServlet方法中,它new了一个DispatcherServlet对象,

然后又返回回去,看到这里和我们在SSM中的配置类里注册Bean并没有什么不同

由此可知,SpringBoot它把这个DispatcherServletAutoConfiguration类写到**.import**文件中然后通过读取这个类,去创建Bean,这个.import文件就是自动装配的核心

6.总结

启动类中的@SpringBootApplication -->

SpringBootApplication类中的@EnableAutoConfiguration -->

EnableAutoConfiguration类中通过@Import({AutoConfigurationImportSelector.class})引用AutoConfigurationImportSelector -->

AutoConfigurationImportSelector类中的getCandidateConfigurations方法告诉了自动配置配置文件的路径 -->

在pom文件找到spring-boot-starter,再找到spring-boot-autoconfigure -->

在外部库中找到 org.springframework.boot:spring-boot-autoconfigure:3.2.4 / spring-boot-autoconfigure-3.2.4.jar!

/META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports文件

所以,我们可以自定义starter,这个项目的META-INF\spring下的.import文件中加入自动装配的全类名,然后再在pom中加入该有依赖,

SpringBoot就会自动加载这个Bean了

[!NOTE]

在SpringBoot 2.7版本之前这个自动配置文件是spring.factories

在2.7到3.0是兼容spring.factories和 .imports文件

在3.0以后使用的是 .import文件

.import文件全名org.springframework.boot.autoconfigure.AutoConfiguration.imports

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值