SpringBoot-starter的原理
⽬录
⼀、前⾔
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>
spring ioc注解<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&batis.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的⼈来说,可能只知道配置属性是在l或l中添加,但他们各⾃的属性都有哪些,具体怎么配置,却⽆从下⼿。这⾥先解决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。这⾥也解释了为什么我们在l中只配置了数据源,⽽没有配置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和
⾄SpringBoot-starter原理之⼿写。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论