SpringBoot(零xml配置的Spring框架)
一
1Spring缺点
(1)Spring组件是轻量级的,但是它的配置确是重量级的 (2)依赖版本之间的冲突 |
2SpringBoot概念
SpringBoot是Spring公司的一个顶级项目,使用它在编写项目时不需要编写xml文件了,它主要用到的是启动器,启动器实际就是一个依赖,这个依赖中包含了整个这个技术的相关jar包,还包含了这个技术的自动配置,当然还需我们少量配置,在properties文件和yml文件中,使用SpringBoot整合其他技术时首先需要考虑导入启动器。 如果是Spring自己封装的启动器的artifact id名字满足:spring-boot-starter-xxxx 如果是第三方公司提供的启动器的artifact id名字满足:xxxx-spring-boot-starter |
3SpringBoot特征
|
4SpringBoot版本介绍
SNAPSHOT:快照版,即开发版 CURRENT:最新版,但不一定是最稳定版 GA:正式发布的版本(2.2.10和2.1.17) |
5SpringBoot的核心
起步依赖:起步依赖本质是一个Maven对象模型,简单说是将某种功能的坐标打包到一起,并提供一些默认的功能 自动配置:自动配置是SpringBoot的应用程序在启动的过程中,考虑众多因素,才决定配置该用哪个,不该用哪个 |
二
6第一个基于SpringBoot的SpringMVC项目
(1) spring-boot-starter-parent spring-boot-starter-web (2)新建启动类并添加注解并添加代码 启动类在启动时会做注解扫描,扫描位置为同包或者子包下的注解,所以启动类的位置应放于包的根下(一般放在和controller,service,mapper,pojo平级) //启动类:是springboot项目程序入口
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class,args);
}
} |
7启动类与启动器区别
(1)启动类表示项目的启动入口 (2)启动器表示jar包的坐标 |
8SpringBoot继承的实现方式
1中就是一个简单的继承方式 |
9SpringBoot依赖的实现方式
公司中可能出现必须继承某个项目,如果SpringBoot用了继承,就不能继承别的项目了,所以SpringBoot还提供了依赖的方式 <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> 打包可能出问题 |
10IDEA快速构建SpringBoot项目
(1) (2) (3) (4) |
11SpringBoot原理分析
|
12SpringBoot核心注解
@SpringBootApplication |
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan |
@SpringBootConfiguration @EnableAutoConfiguration ServletWebServerFactoryAutoConfiguration, 底层会创建tomcat对象 开启自动配置 @ComponentScan 包扫描 |
三
13SpringBoot配置文件
学习文档: https://docs.spring.io/spring-boot/docs/2.1.18.RELEASE/reference/html/common-application-properties.html Common application properties (1)properties格式 配置Tomcat端口 server.port=8888 例如 server.port=8888
spring.datasource.driver-class-name=
spring.datasource.url=
spring.datasource.data-username=
spring.datasource.data-password= (2)yml格式 yml格式要求: 【1】通过首行缩进表示上下级 【2】注意空格 【3】相同的部分只出现一次 【4】大小写敏感 例如 server:
port: 9999
spring:
datasource:
password:
url:
driver-class-name:
data-username: yml格式支持json person: {age:18,name:zs} person2: age: 18 name: zs yml格式支持数组 city: [beijing,tianjin,shanghai,shenzhen]
city2:
- beijing
- tinajin
- sahnghai
- shenzhen |
14配置文件存放位置
(1)当前项目根目录中【a】其次 效果图 (2)当前项目根目录下的一个/config子目录中【b】优先级最高
(3)项目的resources即classpath根路径中(脚手架默认的位置)【c】最后 (4)项目的resources即classpath根路径下的/config目录中【d】一般 |
15SpringBoot配置文件加载顺序(也就是优先级)
【2】同一个配置属性,在多个配置文件都配置了,默认使用第一个读取到的,后面读取的不覆盖前面读取到的 2.不同位置配置文件的加载顺序,看13 b>a>d>c 总结c是脚手架,但是优先级最低 有config文件夹的优先级更高 根目录最高 |
16bootstrap配置文件加载优先于application
17SpringBoot目录结构
F:\workspace\springboot\demo1\src\main\resources 这个文件夹下不止有config文件夹,还应有三个文件夹 其中,public放公共的请求资源 static放静态资源,可以有js、css、图片、不被服务器解析(不用配静态资源放行),访问图片时不需要输入static了,因为是特殊含义的目录 templates放页面,不推荐使用jsp,官方推荐themleaf,这个文件夹相当于web下的webinfo,webinfo不能直接访问,只能通过转发的方式访问 用public和templates做视图显示 |
四
18SpringBoot整合Mybatis
<!--springboot整合mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--mysql的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency> 桥梁也不需要了,但是web需要(ssm) <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> 在启动类上加注解扫描mapper层 此时在mapper层是用注解写的sql,如果想用xml写sql,则需要在pom.xml中写资源拷贝插件,如果不用资源拷贝插件,则把xml放在resource下,在resource下新建一个文件夹放xml,在配置文件中配置数据库的四部分和给实体类起别名,还要配置mapper-locations知名xml文件路径。 接口和xml分开写,可以使用插件MybatisX来定位 |
19SpringBoot整合PageHelper
SpringBoot整合PageHelper不需要做任何配置文件的配置,添加依赖后就可以直接使用 (1)添加依赖 <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency> PageInfo对象把集合对象和分页参数信息全部封装到一起 |
20SpringBoot整合Druid
在内存中一块空间,空间中放置N多个数据库连接对象。对象可以是处于活动状态,也可以是空闲(Idle)状态的。数据库获取连接对象时不在从数据库中获取连接对象,而是从数据库连接池中获取到连接对象,当获取到连接对象后,对象处于活动状态(Active),当连接对象使用完成后,在代码中进行连接关闭,实际上是把连接对象从活动状态变为空闲状态,不是真正的关闭。 在频繁访问数据库(访问频率特别高的)的应用中,使用数据库连接池效率高。 Druid是由阿里巴巴推出的数据库连接池。它结合了C3P0、DBCP、PROXOOL等数据库连接池的优点。之所以从众多数据库连接池中脱颖而出,还有一个重要的原因就是它包含控制台。 不要使用高版本的 |
spring:
datasource:
# 使用阿里的Druid连接池
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# 填写你数据库的url、登录名、密码和数据库名
url: jdbc:mysql://127.0.0.1:3306/tingyu?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 username: root
password: root
druid:
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
# 配置DruidStatFilter
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置DruidStatViewServlet
stat-view-servlet:
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
allow: 127.0.0.1,192.168.163.1 # IP黑名单 (存在共同时,deny优先于allow)
deny: 192.168.1.188
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: 123456
mybatis:
mapper-locations: classpath:mybatis/*.xml |
21SpringBoot整合LogBack
不需额外添加LogBack的依赖,启动器spring-boot-starter或者spring-boot-starter-web已经包含了LogBack的依赖
|
22SpringBoot整合FreeMarker
(1)FreeMarker是一种模板引擎(非ajax) 模板引擎是一种基于模板和要改变的数据来生成输出文本的通用工具 模板+数据模型=输出 freemarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件) (2) FreeMarker的入门案例 【1】导入FreeMarker启动器 【2】在templates下新建html,然后改变后缀为.ftl (3)前台接收值使用FreeMarker的语法 ${Request.msg},msg不是固定的,是后台设置的 (4)FreeMarker常用指令 【1】注释: <#--和--> 【2】插值:${Request.msg} 【3】FTL指令:和HTML标记类似 <#开头 1)循环指令:<#list 要遍历的集合名 as 遍历集合中每一个对象> </#list> 例如:li是后台传过来的值,stu后边的属性其实用的反射get方法获得的,_index得到的是循环的下标,从0开始 <#list li as stu> <tr> <th>${stu_index}</th> <th>${stu.id}</th> <th>${stu.name}</th> <th>${stu.sex}</th> </tr> </#list> 2)if指令 <#if > </#if> 例如: <#if stu_index%2==0> <tr bgcolor=”red”> </#if> <#if stu_index%2!=0> <tr bgcolor=”black”> </#if> 3)支持运算符 4)空值处理:?? <#if stus??> <list stus as stu> </#list> </#if> 5)内建函数 内建函数语法格式:变量+?+函数名称 【4】文本: |
五
23Thymeleaf
Thymeleaf将html在浏览器中正确显示,Thymeleaf放在SpringBoot项目中放入到resources/templates中。这个文件夹中的内容分是无法通过浏览器URL直接访问的(和WEB-INF效果一样),所有Thymeleaf必须先走控制器 |
使用步骤 (1)在pom.xml中添加Thymeleaf启动器 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.2</version>
</dependency> (2)为了有提示,修改html页面中<html>标签 修改为<html xmlns:th="http://www.thymeleaf.org" > (3)写控制器,因为必须走控制器 自动增加前缀后缀 【1】thymeleaf的前缀后缀 【2】freemarker的前缀后缀 它是根据加的启动器的不同来区分是thymeleaf还是freemarker 怎么使用thymeleaf接受后台数据? th:text 是把值放到双标签内部 th:value是把值放到单标签的value属性中 效果 |
24Thymeleaf语法
(1)th:text(双标签) <!--直接向标签内部填充内容,清空原有内容-->
<span th:text="shuai"></span>
<!--从作用域中获取name输入到标签内部-->
<span th:text="${name}"></span> (2)th:value(单标签) 表单元素,设置表单元素value属性值 <input type="text" th:value="${name}"/> (3)th:if 进行逻辑判断,如果成立该标签生效(显示),如果不成立,该标签无效(不显示) 注意:判断条件中逻辑判断符号写在${}外面 (4)th:each li是后台传的集合,stu是集合中每一个对象,$不能直接用,必须依附于标签 <table>
<tr th:each="stu:${li}">
<th th:text="${stu.id}"></th>
<th th:text="${stu.name}"></th>
<th th:text="${stu.age}"></th>
<th th:text="${stu.sex}"></th>
<th>操作</th>
</tr>
</table> 如果想要判断奇数行还是偶数行在每一个对象后面加一个属性(随便起)i,然后在${i}去打点调方法 如果想要实现隔行变色,使用th:class th:class=${i.even}?a:b (5)th:href 删除时这样写不行<th <a href="remove?id=${id}">删除</a></th> 删除时这样写也不行<th<a th:href="remove?id=${id}">删除</a></th> 怎么写呢? <th<a th:href="@{remove(id=${stu.id},name='zs')}">删除</a></th> (6)th:onclick 在触发事件时 <th<a href="javascript:void(0)" onclick="remove(${stu.id})">删除</a></th> 以上写法不行 怎么写呢?(加引号) <th<a href="javascript:void(0)" onclick="remove('+${stu.id}+')">删除</a></th> 总结:什么时候加th,什么时候不加th呢? 如果用到后台的值了(java代码),就需要加th,如果是正常的写法则不用 |
25Thymeleaf字符串操作
Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。 (1)使用内置对象的语法 【1】引用内置对象需要使用# 【2】大部分内置对象的名称都以s结尾。如:strings、numbers、dates
(2)日期格式化处理
|
26Thymeleaf操作域对象
(1)HttpServletRequest
(2) HttpSession
(3) ServletContext
|
27SpringBoot开发者工具
使用开发者工具包不需要重启。监听内容改变 (1)在pom.xml中添加依赖 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.4.2</version>
</dependency> (2)设置IDEA自动编译 (3)修改Registry Ctrl+Shift+Alt+/ |
28SpringBoot打包
点击IDEA右侧Maven -- > Lifecycle --> install 打包后的内容出现在target根目录 1.1运行jar包项目① 在本地windows系统中运行 把此jar粘贴到任意目录,示例粘贴到D根目录下 启动windows命令行。依次输入: # d: # java-jar 文件名.jar 也可以新建一个批处理文件,例如:run.bat,在文件中添加
② 部署到linux 和windows步骤一样。把jar上传到linux后放入到任意目录中,进入到jar所在目录 后执行java -jar 文件.jar 就可以运行。 也可以在jar所在文件夹中新建一个文件,执行运行文件。 # vim startup.sh 文件中输入java -jar 文件.jar # chmod a+x startup.sh # ./startup 1.2 SpringBoot项目打包成war包① 如果我们当前的maven项目本身就是war类型的项目,直接打包即可 但是如果我们当前的maven项目是jar类型的项目,我们需要将项目修改 为war类型,修改项目的pom文件,使用packaging标签设置值为war 并且需要在项目中创建webApp文件夹,并设置为资源文件夹。 ② 在SpringBoot的pom文件中将web启动器中的tomcat依赖排除 因为我们打包的war项目要放在自己的tomcat服务器中运行,需要 排出SpringBoot项目内置的tomcat。然后再手动的将tomcat插件 依赖过来,并设置其scope值为provided。
③ SpringBoot的启动类继承SpringBootServletInitializer,并重写configure
④ 使用install命令打包项目,并将war包放到tomcat下的webapps下,启动 ⑤如果我们使用的是tomcat7则需要将javax.el-api-3.0.0.jar包放到tomcat下 的lib目录中。 |
29异常页面
默认情况,Spring Boot项目错误页面如下。 当项目实际上线,如果给用户显示这个页面就不是很友好。当系统出现异常时应该给用户显示更加友好的错误页面。
在templates/下新建error文件夹,在error中新建:状态.html的页面。例如当出现500时显示的页面为500.html 2使用x进行模糊匹配当出现5开头状态码的错误时,显示页面可以命名为5xx.html 当出现50开头状态码的错误时,显示页面可以命名为50x.html 3统一错误显示页面在templates下新建error.html。如果项目中不存在具体状态码的页面或没有使用x成功匹配的页面时,显示error.html作为错误显示页面。 十七、异常处理机制在Spring Boot项目中除了设置错误页面,还可以通过注解实现错误处理。 常见方式如下: 在控制器类中添加一个方法,结合@ExceptionHandler。但是只能对当前控制器中方法出现异常进行解决。 新建全局异常类,通过@ControllerAdvice结合@ExceptionHandler。当全局异常处理和局部处理同时存在时,局部生效(就近原则)
|
30SpringBoot整合junit
在src/main/test里面新建com.bjsxt.MyTest 注意:
|
31SpringBoot整合Quartz
新建Maven项目SpringQuartz。
由于spring-boot-starter-web并没有依赖spring-conext-support,所以需要单独添加此依赖。
新建com.bjsxt.QuartzApplication启动类
新建com.bjsxt.scheduled.DemoScheduled类。 注意类上有@Component注解,启动项目就需要加载类及类中的@Scheduled注解。
Cron表达式是一个字符串,分为6或7个域,每一个域代表一个含义 Cron有如下两种语法格式: (1) Seconds Minutes Hours Day Month Week Year (2)Seconds Minutes Hours Day Month Week
corn从左到右(用空格隔开): 秒 分 小时 月份中的日期 月份 星期中的日期 年份
Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下: ●星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”; ●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于占位符; ●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12; ●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五; ●斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y; ●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五; ●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围; ●LW组合:在日期字段可以组合使用LW,它的意思是当月的最后一个工作日; ●井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发; ● C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。 Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。 例子: @Scheduled(cron = "0 0 1 1 1 ?")//每年一月的一号的1:00:00 执行一次 @Scheduled(cron = "0 0 1 1 1,6 ?") //一月和六月的一号的1:00:00 执行一次 @Scheduled(cron = "0 0 1 1 1,4,7,10 ?") //每个季度的第一个月的一号的1:00:00 执行一次 @Scheduled(cron = "0 0 1 1 * ?")//每月一号 1:00:00 执行一次 @Scheduled(cron="0 0 1 * * *") //每天凌晨1点执行一次 // 每月 星期12356 8点 10分 15s Cron = 15 10 8 ? * 1,2,3,5,6
Scheduled是Spring3.0后内置的定时任务器。通过Scheduled可以完成周期的执行一些功能。存在于spring-conext-support.jar中。 在SpringBoot中使用Scheduled非常简单,只需要在对应的方法上添加@Scheduled注解在配置对应的参数就可以完成。
官方解释 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目。可以方便的继承在Java项目中完成任务调度功能。总体功能和java.util.Timer很像,但是要比Timer功能更加强大。且不像Scheduler执行一个固定的任务,在Quartz可以对任务进行操作,新增任务,删除任务等。 例如: 每天固定时间执行任务! 每隔2天执行一次任务! 这些都是任务调度。Quartz都可以轻松地完整这些事情。 5.2核心 Quartz核心包含四个概念。 5.2.1Job 表示一个工作,要执行的具体内容。 5.2.2JobDetail--完成一件怎样的事情 表示一个具体的可执行的调度任务。JobDetail除了包含Job还包含了任务调度和策略。 5.2.3Trigger--什么时候去调用 触发器。配置调度参数,定义什么时候去调用。 5.2.4Scheduler--结合上面两者什么时间完成XX事情 表示调度容器。Scheduler可以包含多个JobDetail和Trigger。 案例: 项文峰中午3点 抽田璐 JobDetail:项文峰爱抚田璐 Trigger:中午3点 Scheduler:我就是调度员--》中午3点项文峰爱抚田璐 4.3入门案例实现 1依赖引入
2Job工作定义
3定义实现执行过程
5 SpringBoot整合Quartz引入数据库实现新建Maven项目SpringQuartz 5.3新建数据库导入数据 在MySQL中新建数据库quartz。 运行quartz.sql文件,导入数据文件(在当前版本中使用数据库初始化文件属性always不生效。) 5.4添加依赖
5.5配置配置文件 新建application.yml,并配置数据源
5.6新建静态类 新建com.bjsxt.statics.QuartzStatic。为了记录每次执行Job的时间,定义一个静态常量。
5.7新建Job 新建com.bjsxt.job.MyJob定义Job的内容。
5.8新建启动类 新建com.bjsxt.QuartzApplication
5.9新建测试类 新建测试类com.bjsxt.MyTest。 在测试类中测试Quartz中新增、修改、删除、暂停、恢复、查询等功能。在每个功能执行完成后要注意数据库中数据的变化。
|
32SpringBoot中Bean管理
Spring Boot 由于没有XML文件,所以所有的Bean管理都放入在一个配置类中实现。 配置类就是类上具有@Configuration的类。这个类就相当于之前的applicationContext.xml |