Spring boot starter实现原理
- 一、前言:
- 二、实现原理
- 2.1 Springboot 在背后帮我们做了哪些事情
- 2.2 Springboot 怎么去做?
- 2.3 什么是starter
- 2.4 SpringBoot的诸多配置
- 2.5 常用的starter
- 2.5.1. spring-boot-starter-parent(控制版本信息)
- 2.5.2. spring-boot-starter(核心启动器)
- 2.5.3. spring-boot-starter-web
- 2.5.4. spring-boot-starter-test
- 2.5.5. spring-boot-starter-jdbc
- 2.5.6. mysql-connector-java
- 2.5.7. mybatis-spring-boot-starter
- 2.5.8. druid-spring-boot-starter
- 2.5.9. mybatis-plus-boot-starter
- 2.5.10. spring-boot-devtools
- 2.6 总结
一、前言:
1.1 背景
J2EE笨重的开发、繁琐的配置、低下的开发效率、复杂的部署流程、第三方技术集成难度大。
SpringBoot的出现就是为了简化开发、去繁从简。
接触过SpringBoot的开发者都知道可以使用SpringBoot快速的开发基于Spring框架的项目。由于围绕SpringBoot存在很多开箱即用的Starter依赖,使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。这也是大家放弃原始SSM框架,而采用SpringBoot的主要原因。
例如:我们想要在SpringBoot项目中集成Redis,那么我只需要加入spring-data-redis-starter的依赖,并简单配置一下连接信息以及Jedis连接池配置就可以。这为我们省去了之前很多的配置操作。甚至有些功能的开启只需要在启动类或配置类上增加一个注解即可完成。
1.2 优点
创建独立的Spring应用
内嵌Tomcat、Jetty或Undertow(无需部署war包)
提供自用的starter来简化构建配置
提供指标监控、运行状况检查和外部化配置
没有代码生成,也不需要XML配置(约定大于配置),开箱即用
于云计算的天然继承
那么它的实现原理是什么呢?
二、实现原理
2.1 Springboot 在背后帮我们做了哪些事情
首先讲一下原理,我们知道在使用一个starter的时候,只需要将相应的依赖添加到Maven的pom配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。
那么,SpringBoot 帮我们做了哪些事情呢?想想我们自己搭建web开发环境需要做哪些工作?
通常搭建一个基于spring的web应用,我们需要做以下工作:
六个方面:
1、pom文件中引入相关jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java
等等相关jar …
2、配置web.xml,Listener配置、Filter配置、Servlet配置、log4j配置、error配置 …
3、配置数据库连接、配置spring事务
4、配置视图解析器
5、开启注解、自动扫描功能
6、配置完成后部署tomcat、启动调试
这么多的步骤,用SpringBoot之后,都省去了,是不是很方便?答案是肯定的。从此,我们也可以想到,这么多步骤都是SpringBoot替我们完成,而且是按照某种默认的规则进行的。这个规则就是约定大于配置。
2.2 Springboot 怎么去做?
那么 SpringBoot 是如何知道怎么去做,要做哪些事情,要实例化哪些类,并进行自动配置的呢?==
一共三个步骤:
1) SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。注释:SPI的英文名称是Service Provider Interface,是Java 内置的服务发现机制
2)根据 spring.factories配置加载AutoConfigure类。
3)根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。
我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。
2.3 什么是starter
SpringBoot-starter是一个集成接合器,也叫作场景启动器,完成两件事:
1) 引入模块所需的相关jar包
2) 自动配置各自模块所需的属性
2.4 SpringBoot的诸多配置
得益于starter的作用,使用SpringBoot确实方便,但对刚刚上手SpringBoot的人来说,可能只知道配置属性是在application.xml或application.yml中添加,但他们各自的属性都有哪些,具体怎么配置,却无从下手。这里先解决SpringBoot-starter中各属性的配置问题。
2.5 常用的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等,各自都代表了一个相对完整的功能模块。
2.5.1. spring-boot-starter-parent(控制版本信息)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
这是Spring Boot的版本仲裁中心,控制了所有依赖的版本号。
好处:以后我们导入依赖默认是不需要写版本; 下面看一下具体的在哪里控制的版本。
如图所示:按住Ctrl键点击框中的内容,会打开spring-boot-starter-parent-2.2.4.RELEASE.pom文件
在打开的文件中,按住Ctrl键用同样的方式点击,spring-boot-dependencies中的spring-boot-dependencies,会打开spring-boot-dependencies-2.2.4.RELEASE.pom文件,此文件中就汇总的我们常用类库的版本,如下所示:
对于jar包版本的依赖,Springboot已经在此pom文件中定义好了部分常用的,使用时不用配置。当然了,没有在dependencies里配置的依赖,还是需要自己配置版本的。
2.5.2. spring-boot-starter(核心启动器)
Spring Boot的核心启动器,包含了自动配置、日志和YAML
2.5.3. spring-boot-starter-web
web的场景,自动帮我们引入了web模块开发需要的相关jar包
上面两者的区别是:是否web应用程序。
2.5.4. spring-boot-starter-test
springboot程序测试依赖,这个引用时需要注意生效的范围,如果设置了test,那么在非测试目录无法使用。
2.5.5. spring-boot-starter-jdbc
Spring-boot-starter-jdbc是springboot提供的,但是如果引入了mybatis-spring-boot-starter,就不再需要单独引入spring-boot-starter-jdbc了,这是由于mybatis已经包含了此依赖。
2.5.6. mysql-connector-java
mysql连接驱动
2.5.7. mybatis-spring-boot-starter
- 自动检测现有的DataSource
- 将创建并注册SqlSessionFactory的实例,该实例使用SqlSessionFactoryBean将该DataSource作为输入进行传递
- 将创建并注册从SqlSessionFactory中获取的SqlSessionTemplate的实例。
- 自动扫描您的mappers,将它们链接到SqlSessionTemplate并将其注册到Spring上下文,以便将它们注入到您的bean中。
使用了该Starter之后,只需要定义一个DataSource即可(application.properties或application.yml中可配置),它会自动创建使用该DataSource的SqlSessionFactoryBean以及SqlSessionTemplate。会自动扫描你的Mappers,连接到SqlSessionTemplate,并注册到Spring上下文中。
application.yml文件中配置:
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: com.ieslab.powergrid.entity
2.5.8. druid-spring-boot-starter
阿里巴巴的数据库连接池启动器,效率较好,而且具备监视界面,相关配置文件如下:
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
#初始化大小
initialSize: 5
#最小值
minIdle: 5
#最大值
maxActive: 20
#最大等待时间,配置获取连接等待超时,时间单位都是毫秒ms
maxWait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接
timeBetweenEvictionRunsMillis: 60000
#配置一个连接在池中最小生存的时间
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,
#'wall'用于防火墙,SpringBoot中没有log4j,我改成了log4j2
filters: stat,wall,log4j2
#最大PSCache连接
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# 配置StatFilter
web-stat-filter:
#默认为false,设置为true启动
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
#配置StatViewServlet
stat-view-servlet:
url-pattern: "/druid/*"
#允许那些ip
allow: 127.0.0.1
login-username: admin
login-password: 123456
#禁止那些ip
deny: 192.168.1.102
#是否可以重置
reset-enable: true
#启用
enabled: true
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: com.ieslab.powergrid.entity
2.5.9. mybatis-plus-boot-starter
Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
使用MyBatis的时候,经常需要书写类似SELECT id,name,age,email FROM user WHERE
id=#{id}这样的语句,而且当增加字段后,还需要逐条语句都检查。
使用MyBatis-Plus后可以摆脱大部分此类简单的CRUD操作(通用Mapper也可以)。
2.5.10. spring-boot-devtools
开发工具,热部署时使用。
其他的启动器此处不再叙述,请查阅相关专业资料
2.6 总结
项目中,尽可能使用Springboot提供的启动器,不要随意引用。