前言

“我正在参加「启航方案」”

作者简介: 不愿过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法处理繁琐问题,让杂乱的问题变得通俗易懂。

支撑作者: 点赞、重视、留言~

咱们都知道,Spring 的功用十分强壮,但也存在一些坏处。例如咱们需求手动去装备许多的参数,需求咱们办理许多的 jar 包等等。后来,官方为了简化装备,一起能够让开发者们能更好的专心于事务的开发,Spring 官方引进了 SpringBoot 的概念。提到 SpringBoot 各位小伙伴肯定是不陌生了,咱们简直每天都在和它打交道,便是不知道各位小伙伴在运用 SpringBoot 的时分有没有留意过 pom.xml 中的 starter 依靠呢~ 今天大聪明就和我们深入浅出聊 SpringBoot 中的 starter 机制

SpringBoot 中的 starter 机制

什么是 starter

SpringBoot 在装备上相比 Spring 要简略许多, 其中心在于 spring-boot-starter,在运用 SpringBoot 来建立一个项目时,只需求引进官方供给的 starter 后就能够直接运用,免去了各种繁琐的装备流程。简略来讲便是,starter 帮助开发者们引进了一些相关依靠和一些初始化的装备,然后能够让开发者们更专心于开发。Spring 官方供给了许多 starter,第三方也能够界说 starter。为了加以区别,starter从称号进步行了如下规范:

  • Spring 官方供给的 starter 称号为 spring-boot-starter-xxx,例如 spring-boot-starter-web
  • 第三方供给的 starter 称号为 xxx-xxx-boot-starter,例如由苞米豆供给的 mybatis-plus-boot-starter

提到这,各位小伙伴可能有疑问了,SpringBoot 为什么能够帮咱们简化项目的建立的工作呢?它是怎么做到这点的呢?

其实这就要归功于它供给的两大功用了,起步依靠和主动装备。

起步依靠

起步依靠,其实便是将具有某种功用的相关依靠打包到一同,这样能够简化依靠导入的进程(咱们能够将其理解为依靠整合)。例如,咱们在导入 spring-boot-starter-web 时,和 web 开发相关的依靠都一同导入到项目中了。咱们点开 spring-boot-starter-web 依靠后就能够发现,它下面还包含着众多所需求的基础依靠

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

主动装备

主动装备,望文生义便是无须手动装备 xml 文件,当咱们引进相关依靠后就能够主动装备并办理 bean,极大的简化了开发进程。SpringBoot 完结主动装备共分为五个要害的过程:

  1. 根据装备文件的 Bean 装备
  2. 主动装备条件依靠
  3. Bean 参数获取
  4. Bean 的发现
  5. Bean 的加载

接下来咱们以 mybatis-plus-boot-starter 为例子,具体说一下这五个流程

① 根据装备文件的 Bean 装备 当咱们引进了 mybatis-plus-boot-starter 后,咱们能够从依靠中找到对应的 jar 包,咱们翻开 jar 包能够找到一个要害的 MybatisPlusAutoConfiguration 装备文件,如下图所示

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

了解 @Configuration 和 @Bean 这两个注解的小伙伴们或许现已明白了。这两个注解一同运用就能够创立一个能够替代 xml 装备文件的装备类。增加了 @Configuration 注解的类能够看作是能让 Spring IOC 容器办理的 Bean 实例的工厂。@Bean 注解能够告知 Spring,带有 @Bean 的注解办法将回来一个目标,而且该目标需求被注册到 Spring 容器中。所以上面的 MybatisPlusAutoConfiguration 装备类,主动帮咱们生成了 sqlSessionFactory 等重要的实例并将他们交给 Spring 容器办理,然后完结 Bean 的主动注册。

② 主动装备条件依靠

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
经过 MybatisPlusAutoConfiguration 装备文件中增加的 @ConditionalOnClass 和 @ConditionalOnSingleCandidate 注解能够发现,需求完结主动装备是有依靠条件的,即需求在当时类的途径上存在 SqlSessionFactory.class 和 SqlSessionFactoryBean.class,一起需求存在已完结主动注册的 DataSource Bean,才能够完结主动装备。

这里咱们趁便再说几个特别的注解

  • @ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
  • @ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
  • @ConditionalOnClass:当classpath类途径下有指定类的条件下进行实例化。
  • @ConditionalOnMissingClass:当类途径下没有指定类的条件下进行实例化。
  • @ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
  • @ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
  • @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
  • @ConditionalOnExpression:根据SpEL表达式的条件判别。
  • @ConditionalOnJava:当JVM版别为指定的版别范围时触发实例化。
  • @ConditionalOnResource:当类途径下有指定的资源时触发实例化。
  • @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
  • @ConditionalOnSingleCandidate:当指定的Bean在容器中只要一个,或许有多个可是指定了首选的Bean时触发实例化。

③ Bean 参数获取

要完结 mybatis-plus 的主动装备,需求在装备文件中供给相关的装备参数,咱们能够看到 MybatisPlusAutoConfiguration 装备文件中还写上了 @EnableConfigurationProperties 注解

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

咱们持续追踪源码,翻开 MybatisPlusProperties.class 文件后能够发现,这个类上写着 @ConfigurationProperties 注解,这个注解的效果便是把 .yml 文件或许 .properties 装备文件中的装备参数信息封装到 @ConfigurationProperties 注解标注的 Bean (即 MybatisPlusProperties )的相应属性上,而 @EnableConfigurationProperties 注解的效果则是使 @ConfigurationProperties 注解生效。

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

④ Bean 的发现 SpringBoot 默许扫描发动类地点的包下的主类与子类的一切组件,但并没有包含依靠包中的类,那么依靠包中的 Bean 又是怎么被发现和加载的呢?下面咱们就需求从 SpringBoot 项目的发动类开端跟踪了,在发动类上咱们一般会加上 @SpringBootApplication 注解,源码如下

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
咱们都知道 @SpringBootApplication 主要是由三个注解构成:

  1. @SpringBootConfiguration:效果就相当于 @Configuration 注解,被增加了注解的类将成为一个Bean 装备类
  2. @ComponentScan:效果便是主动扫描并加载符合条件的组件,最终将这些 Bean 加载到 Spring 容器中
  3. @EnableAutoConfiguration :借助 @Import 注解的支撑,搜集和注册依靠包中相关的 Bean

接下来咱们再看看 @EnableAutoConfiguration 注解

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
咱们能够发现 @EnableAutoConfiguration 注解又引进了 @Import 注解。导入了 AutoConfigurationImportSelector.class,AutoConfigurationImportSelector.class 源码如下

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
咱们在 AutoConfigurationImportSelector.class 源码中能够发现,getCandidateConfigurations 办法中调用了 SpringFactoriesLoader 类的 loadFactoryNames 办法,咱们持续跟踪源码

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
要害的一行代码呈现了,getResources 办法中调用了一个名为 FACTORIES_RESOURCE_LOCATION 的静态变量,这个静态变量对应的值便是 META-INF/spring.factories

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
看到这里,信任各位小伙伴应该现已清楚了,SpringFactoriesLoader 的 loadFactoryNames 静态办法能够从一切的 jar 包中读取 META-INF/spring.factories 文件,咱们回过头再看一下 mybatis-plus-boot-starter 依靠,能够发现在 mybatis-plus-boot-starter 依靠中的 spring.factories 装备文件里有这样两行装备。也正是经过这个装备,能够让 SpringBoot 加载到 MybatisPlusAutoConfiguration 装备类了。

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制
⑤ Bean 的加载

经过第四步的讲解,信任各位小伙伴也理解了 Bean 的加载流程,SpringBoot 运用 @Import 注解实现了主动装备,从 META-INF/spring.factories 文件中读取到的主装备文件的全类名,这样 SpringBoot 就能够加载到主装备文件中涉及到的 Bean 并完结实例的创立工作。

starter 的要害构成要素

经过上面的讲解,咱们能够总结出构成 starter 的几个要害要素

大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

俗话说,要把大象装冰箱总共分为三步,那么假如自己需求开发一个 starter 总共分为几步呢?没错~~ 也是三步,最终咱们来总结一下开发 starter 的三个过程:

创立一个名为 xxx-xxx-boot-starter的空项目,并在pom.xml文件里引进自己所需的依靠。
开发自己所需的事务逻辑,事务开发完结后创立名为 xxxAutoConfiguration(或 xxxConfiguration) 的主装备类,在该类下界说一些所需的 Bean 实例
创立 spring.factories 装备文件,并在装备文件中引进主装备类org.springframework.boot.autoconfigure.EnableAutoCoinfiguration=xxx.xxx.xxx.xxxAutoConfiguration(或 xxxConfiguration)

小结

本人经验有限,有些地方可能讲的没有特别到位,假如您在阅览的时分想到了什么问题,欢迎在评论区留言,咱们后续再一一探讨‍

希望各位小伙伴动动自己心爱的小手,来一波点赞+重视 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

假如文章中有错误,欢迎我们留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵主意。

爱你所爱 行你所行 听从你心 无问东西