实现starter组件自动装配以及可配置
实现starter组件自动装配以及可配置#
自动装配的包,导入就可以进行自动装配了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
配置文件代码提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Spring Boot自动装配原理
前面说过Spring Boot的特点就是自动装配,相信使用过Spring的读者们都体会过XML配置的复杂,而使用Spring Boot会发现除了导入依赖之外,无需过多的配置即可使用,就算需要配置时也只需要通过配置类或配置文件进行简单配置即可,这样的便利归功于Spring Boot的自动装配。接下来就了解一下Spring Boot究竟如何实现了自动装配。
学过Java的应该都听过SPI机制(JDK内置的一种服务发现机制),而Spring boot正是基于SPI机制的方式对外提供了一套接口规范(当Spring Boot项目启动时,会扫描外部引入的Jar中的META-INF/spring.factories
文件,将文件中配置的类信息装配到Spring容器中),让引入的Jar实现这套规范即可自动装配进Spring Boot中。
所以想要自定义的starter组件实现自动装配,只需要在项目的 resources
中创建 META-INF
目录,并在此目录下创建一个 spring.factories
文件,将starter组件的自动配置类的类路径写在文件上即可。
项目代码-META-INF/spring.factories
// 添加项目的自动配置类的类路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.lucas.check.config.CheckAutoConfigure
虽然已经解决了自定义starter实现自动装配,但是有兴趣的还是接着了解一下底层自动装配的过程。那么Spring Boot是如何找到 META-INF/spring.factories
的文件并进行自动配置的呢?
深入源码解析自动装配过程
-
Spring Boot项目在启动类上都会有一个
@SpringBootApplication
注解,这个注解可以看作是@Configuration
、@EnableAutoConfiguration
、@ComponentScan
的集合,而自动装配原理就在其中的@EnableAutoConfiguration
中,这个注解作用是开启自动配置机制。 -
@EnableAutoConfiguration
中实现自动装配核心功能的是@Import
,通过加载自动装配类AutoConfigurationImportSelector
实现自动装配功能。 -
深入
AutoConfigurationImportSelector
代码发现该类实现了ImportSelector
接口同时实现了该接口的selectImports
方法,这个方法用来获取所有符合条件的类的全限定名(为什么是符合条件,只在后续按需装配中说明),并且将这些类加载进Spring容器中。 -
再深入
selectImports
方法中会发现这个
getAutoConfigurationEntry()
方法才是最终获取到
META-INF/spring.factories
文件的方法。
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { // 第一步:先判断是否开启了自动装配机制 if (!this.isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } else { // 第二步:获取@SpringBootApplication中需要排除的类(exclude和excludeName属性),通过这两个属性排除指定的不需要自动装配的类 AnnotationAttributes attributes = this.getAttributes(annotationMetadata); List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes); // 第三步:获取需要自动装配的所有配置类 configurations = this.removeDuplicates(configurations); Set<String> exclusions = this.getExclusions(annotationMetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.getConfigurationClassFilter().filter(configurations); this.fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); } }
到这里便是SpringBoot的自动装配原理整个过程(可能描述的不完整,有兴趣的可以去找找资料看看)。
抛出问题:刚刚提到的Spring Boot只会加载符合条件的类是怎么回事?
Spring Boot其实并不会加载 META-INF/spring.factories
文件下的所有类,而是按需加载,怎么个按需加载呢?
Spring Boot可以通过@ConditionalOnXXX
满足条件时加载(即按需加载),下面列举一些常用的注解:
@ConditionalOnBean
:当容器里存在指定Bean时,实例化(加载)当前Bean。@ConditionalOnMissingBean
:当容器里不存在指定Bean时,实例化(加载)当前Bean。@ConditionalOnClass
:当类路径下存在指定类时,实例化(加载)当前Bean。@ConditionalOnMissingClass
:当类路径下不存在指定类时,实例化(加载)当前Bean。@ConditionalOnProperty
:配置文件中指定的value属性是指定的havingValue属性值时,实例化(加载)当前Bean。
作者:Esofar
出处:https://www.cnblogs.com/firsthelloworld/p/17750874.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本