SpringBoot-starter的原理

目录

一、前言

1.1 SpringBoot的优点

1.2 SpringBoot-starter的作用

二、SpringBoot-starter解析

2.1 SpringBoot搭建SSM

2.2 SpringBoot的诸多配置

2.3 SpringBoot-starter自动配置bean


一、前言

1.1 SpringBoot的优点

SpringBoot是新一代流行的Spring应用开发框架,它具有更多的优点:

  • 创建独立的Spring应用
  • 内嵌Tomcat、Jetty或Undertow(无需部署war包)
  • 提供自用的starter来简化构建配置
  • 提供指标监控、运行状况检查和外部化配置
  • 没有代码生成,也不需要XML配置(约定大于配置)

1.2 SpringBoot-starter的作用

SpringBoot拥有很多方便使用的starter(Spring提供的starter命名规范spring-boot-starter-xxx.jar,第三方提供的starter命名规范xxx-spring-boot-starter.jar),比如spring-boot-starter-log4j、mybatis-spring-boot-starter.jar等,各自都代表了一个相对完整的功能模块。

SpringBoot-starter是一个集成接合器,完成两件事:

  • 引入模块所需的相关jar包
  • 自动配置各自模块所需的属性

二、SpringBoot-starter解析

2.1 SpringBoot搭建SSM

我们使用SpringBoot新建一个web工程(SSM),看看他的依赖都有哪些:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>

可见,使用SpringBoot-starter来搭建web工程相当方便,不像以前搭建SSM,需要将那么多jar包依赖逐个加入到Maven工程,还需考虑jar包之间的版本兼容性等。另外,数据源所需的配置也仅需如下:

spring.datasource.url=jdbc:mysql://100.10.14.116:3306/szhtest2?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=test
spring.datasource.password=test

Mybatis的配置如下:

至此,不需要多余的配置,一个SpringBoot搭建的SSM工程就可以跑了。

2.2 SpringBoot的诸多配置

得益于starter的作用,使用SpringBoot确实方便,但对刚刚上手SpringBoot的人来说,可能只知道配置属性是在application.xml或application.yml中添加,但他们各自的属性都有哪些,具体怎么配置,却无从下手。这里先解决SpringBoot-starter中各属性的配置问题。

以2.1中的示例来看,Mybatis的配置是怎么生效的?查看示例工程的pom依赖:

注意到mybatis-spring-boot-starter帮我们自动依赖了Mybatis所需jar包,其中有一个负责自动配置的mybatis-spring-boot-autoconfigure.jar,紧接着打开此jar,如下:

META-INF/spring-configuration-metadata.json中便是Mybatis在SpringBoot中的所有配置属性和介绍。至此,第一个问题便得到解决。

2.3 SpringBoot-starter自动配置bean

现在已得知jar包是怎么样自动依赖进来,以及他们的配置属性,那么接下来该考虑Mybatis所需的bean(如必需的sqlSessionFactory、sqlSessionTemplate等)是如何被自动加载的?

理所应当地,我们继续去查看mybatis-spring-boot-autoconfigure.jar,注意到里面有一个自动配置的类MybatisAutoConfiguration

(1)@Configuration:被挂上@Configuration注解,表明它是一个配置类,作用等同于xml配置,里面有被@Bean注解的方法,也等同于xml配置的各种<bean>。

(2)@ConditionalOnClass/@ConditionalOnBean:自动配置条件注解,用于在某一部分配置中,将另一模块部分的配置自动加载进来,因为随着系统越来越大,配置内容越来越多,我们应当将Mybatis的配置放在一处,将log4j的配置放在一处,将SpringBoot自身的配置放在一处,当他们需要互相依赖时,可通过这类注解进行自动配置,如下:

@ConditionalOnClass @ConditionalOnMissingClass
@ConditionalOnBean @ConditionalOnMissingBean
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication @ConditionalOnNotWebApplication
@ConditionalOnExpression

@AutoConfigureAfter @AutoConfigureBefore @AutoConfigureOrder(指定顺序)

(3)@EnableConfigurationProperties:启用对@ConfigurationProperties注解的bean的支持,这里对应了配置属性类MybatisProperties,它里面定义了Mybatis的所有配置。

(4)@AutoConfigureAfter:应在其他指定的自动配置类之后应用自动配置。即org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration被自动配置后,才会接着自动配置MybatisAutoConfiguration。这里也解释了为什么我们在application.xml中只配置了数据源,而没有配置Mybatis,但是Mybatis可以正常查库的原因,就是因为它们配置之间的依赖关系。

到这里,差不多明白了starter自动配置bean的方式,但是如若再去深究,各种starter的bean是如何被自动加载的,猜想会不会是项目启动后,SpringBoot自动扫描里面所有的jar包,再去扫描所有的类,从而将各个bean放置IOC容器中。从结果来看,肯定是SpringBoot在启动时确确实实地自动加载了数据源和Mybatis相关的bean,不然他们无法正常工作。

回想在我们启动示例工程时,SpringBoot会自动扫描启动类所在包下的所有类,而如果还去扫描所有的jar包的话,又是具体怎么做到的?不妨从入口类调试一把,在SpringApplication.run(DemoApplication.class, args)打断点,一直追踪到getSpringFactoriesInstances这块:

查看SpringFactoriesLoader.loadFactoryNames的方法注释:

使用给定的类加载器从META-INF / spring.factories加载给定类型的工厂实现的完全限定类名。

有点眼熟,这里的spring.factories刚好也存在于mybatis-spring-boot-autoconfigure.jar中,

继续调试,进入SpringFactoriesLoader.loadFactoryNames

这里用类加载器得到工程中所有jar包中的META-INF/spring.factories文件资源,进而通过此文件得到了一些包括自动配置相关的类的集合,有各种工厂类、监听器、处理器、过滤器、初始化器等等,如下:

最后的org.springframework.boot.autoconfigure.EnableAutoConfiguration集合中当然包括了org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration和org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration。接着必然是将实例化的各个bean放进IOC容器中。

至此我们便明白了SpringBoot是如何自动配置starter里面的bean的。

点此传送至SpringBoot-starter原理之手写。

发布了62 篇原创文章 · 获赞 22 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/songzehao/article/details/100837463