1、SpringBoot简介
Spring应用原始的开发流程复杂,配置繁多,开发效率低,第三方应用继承难度大。Spring公司为 了解决这个问题,研发了SpringBoot。
SpringBoot基本上是Spring框架的扩展,用来简化Spring应用的开发,约定大于配置,去繁从简,很容易就可以生成一个企业级别 的应用。
2、SpringBoot优点
快速创建独立运行的Spring项目以及主流框架集成
使用嵌入式的Servlet容器,应用无需生成war包
starters(场景启动器)自动依赖与版本控制
大量的自动配置,简化开发,也可以修改默认配置
无需配置XML,无代码生成,开箱即用
准生产环境的运行实时应用监控
与云计算的天然集成
3、开发环境准备
JDK 1.8:官方推荐1.7以上
Maven 3.x:方便jar包管理
Idea:根据个人习惯,STS,工具整合Maven
SpringBoot 2.4.0:核心知识点
4、入门案例
导入SpringBoot的父项目
org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE
导入需要的场景启动器,比如:要开发web项目
org.springframework.boot
spring-boot-starter-web
编写启动类:建议启动类放到基础包下
/**
* 通过Main函数去启动SpringBoot应用
* @SpringBootApplication
* 标识这是一个SpringBoot的应用
**/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 要启动Spring应用
// 参数1: @SpringBootApplication所在类的类对象
// 参数2: main函数的参数
SpringApplication.run(Application.class, args);
}
}
运行启动类,可以看到Spring的标识。
简化部署,把项目生成jar包
导入maven打包插件,通过Maven的package命令打包工程
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
通过 java -jar jar包名 命令启动SpringBoot应用
5、SpringBoot探究
(1)pom文件
SpringBoot父项目
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.4.RELEASEversion>
parent>
父项目的父项目:用于管理版本号
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.3.4.RELEASEversion>
<relativePath>../../spring-boot-dependenciesrelativePath>
parent>
spring-boot-dependencies依赖中包含了所有相关依赖jar包的版本;
可以理解为SpringBoot的版本控制中心,以后导入依赖默认是不需要写版本的。
导入场景的依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
(2)启动类
/**
* 通过Main函数去启动SpringBoot应用
* @SpringBootApplication
* 标识这是一个SpringBoot的应用
**/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 要启动Spring应用
// 参数1: @SpringBootApplication所在类的类对象
// 参数2: main函数的参数
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication:标注在类上,说明这个类是SpringBoot的主配置类,SpringBoot要运行这个 类的main方法来启动Spring应用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
a:@SpringBootConfiguration:标注在类上,表示这个类是SpringBoot的配置类;
a1:@Configuration:标注在类上,表示这个类是一个配置类;用于替换配置文件;
@Component:由于配置类也是容器中的一个组件,所以需要添加该注解进行管理
b:@EnableAutoConfiguration:开启自动配置功能;
以前需要配置的东西,现在都不需要配置,由SpringBoot自动配置,就需要添加该注解;
b1:@AutoConfigurationPackage:自动配置包;
@Import({Registrar.class}):Spring的底层注解,用于给容器导入组件。由 Registrar.class 控制。将主配置类 (@SpringBootApplication注解标注的类)所在包及子包下的所有组件扫描到Sring容器中。
b2:@Import({AutoConfigurationImportSelector.class}):给容器中导入组件;
AutoConfigurationImportSelector :自动配置导入的扫描器,将所需要的组件以全类名数组的方式返回,组件就会添加到容中。
会给容器中导入很多配置类(xxxAutoConfiguration),就是给容器中导入场景需要的所有组件并配置好这些组件。
SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader())
SpringBoot在启动时从类路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration 指定的值(类全限定名),将这些值对应的类导入到spring容器中,就可以帮助完成自动配置工作。 (spring-boot-autoconfigure-2.3.4.RELEASE.jar)
6、使用IDE快速创建SpringBoot
免去搭建工程的繁琐流程,只需要关注核心业务开发。
resources中的目录结构:
static:静态资源目录,js、css、img等;
templates:模板页面,由于SpringBoot使用的tomcat是嵌入式的,所以不支持JSP。可以使用模板引擎(Thymeleaf)
applicatioin.properties:配置文件可以,修改默认配置。
SpringBoot使用一个全局的配置文件,配置文件名固定,作用是修改SpringBoot的默认配置。
application.properties(默认加载)
application.yml
YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。
在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。
YAML的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。
它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多
电子邮件标题格式和YAML非常接近)。
YAML 的配置文件后缀为 .yml,如:runoob.yml 。
1、基本语法
key: value
# key和value中间冒号后面必须添加"空格"
key1:
key1-1: value
key1-2: value
......
key2:
key2-1: value
key2-2: value
......
# yaml中以空格的形式(个数不限)表示层级关系,只要是左对齐的空格都属于同一个层级。
属性和值的大小写敏感
2、yml描述数据
(1)字面量:数字、字符串、布尔
age: 28
# 字符串不用添加引号
# "" -> 会把字符中的特殊字符按照自身的含义表示
# '' -> 会把字符中的特殊字符按照字符串表示
name: tom
name: "tom \n jack"
tom
jack
name: 'tom \n jack'
tom \n jack
boolean: true
(2)对象/Map
# 普通写法
student:
name: tom
age: 18
# 行内写法
student: {name: tom, age: 18}
(1)@ConfigurationProperties、@Value
配置文件:
application.yml
# 对象
student:
# 字面量
name: tom
age: 17
birthday: 2019/01/01
married: false
# 集合
list: [1,2,3,4,5]
map: {k1: v1, k2: v2}
# 对象
dog:
name: 豆豆
age: 1
@ConfigurationProperties
/**
* @ConfigurationProperties(prefix = "student")
* 本类中所有的属性和配置文件中的属性绑定,prefix是配置文件中标识该对象的前缀
*
* @Component
* 只有在spring容器中的组件才能使用@ConfigurationProperties功能,所以要添加该注解
*
* @Validated
* 数据校验
*/
@Component
@ConfigurationProperties(prefix = "student")
@Validated
public class Student {
@Email // name的值必须是邮件类型
private String name;
private Integer age;
private Date birthday;
private Boolean married;
private List<Object> list;
private Map<String, Object> map;
private Dog dog;
// 省略set/get
}
校验导包:
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>6.1.5.Finalversion>
dependency>
自定义类在yml中的提示
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
dependency>
@Value
@Component
public class Student {
@Value("${student.name}")
private String name;
@Value("123")
private Integer age;
@Value("2019/01/01")
private Date birthday;
@Value("true")
private Boolean married;
@Value("9,8,7,6")
private List<Object> list;
private Map<String, Object> map;
private Dog dog;
// 省略set/get
}
@ConfigurationProperties和@Value区别:
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入 | 需要在每一个属性上配置 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
松散绑定值得是给属性赋值时的写法:
写法一:标准驼峰命名 -> person.firstName
写法二:大写使用下划线表示 -> person.first_name
写法三:大写使用横杠表示 -> person.first-name
(2)@PropertySource、@ImportResource
@PropertySource:加载指定配置文件
@PropertySource(value = {"classpath:student.properties"})
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
@Value("${person.name}")
private String name;
@Value("123")
private Integer age;
@Value("2019/01/01")
private Date birthday;
@Value("true")
private Boolean married;
@Value("9,8,7,6")
private List<Object> list;
private Map<String, Object> map;
private Dog dog;
// 省略set/get
}
@ImportResource: 导入spring的配置文件,让配置文件中的内容生效; SpringBoot中没有Spring的配置文件,自己编写的配置文件放到资源路径下不能生效。想让Spring配置 文件生效,需要在一个配置类(比如:主程序类)上添加@ImportResource(location={})注解把Spring的 配置文件加载进来。
SpringBoot中给容器中添加组件的推荐方式:
编写一个配置类(把原来的xml使用Java代码描述),使用@Bean给容器中添加组件
/**
* @Configuration:标识该类是一个配置类,用于替换之前的xml文件
*/
@Configuration
public class MyConfig{
/*
* 将方法的返回值添加到容器中
* 容器中这个组件的id默认是方法名
*
* @Bean 用于替换xml中的bean标签
*/
@Bean
public Student student(){
return new Student();
}
}
1、随机
${random.int}、${random.value}、${random.uuid}
2、表达式获取配置的值
student.name=Peter_{random.uuid}
student.age=18
student.birthday=2019/01/01
student.married=false
student.list=1,2,3,5,6
student.map.k1=v1
student.map.k2=v2
student.dog.name=${student.name:小狗}
student.dog.age=2
1、导包
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.3version>
dependency>
2、启动类上添加接口扫描
@SpringBootApplication
// 扫描mapper接口
@MapperScan(basePackages = "com.soft.mapper")
// 加载指定properties文件
@PropertySource(value = {"classpath:jdbc.properties"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3、配置文件中配置数据源和映射文件
# 数据源
spring:
datasource:
driver-class-name: ${jdbc.driver}
url: ${jdbc.url}
username: ${jdbc.username}
password: ${jdbc.password}
# mybatis配置
mybatis:
type-aliases-package: com.soft.entity # 实体类起别名
mapper-locations: com/soft/mapper/*.xml # 映射文件扫描
configuration:
call-setters-on-nulls: true # map映射为空
由于springboot默认是用logback的日志框架的,所以需要排除logback,不然会出现jar依赖冲突的 报错;
1、导包
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
2、将log4j2.xml文件拷贝到resources目录下即可
Thymeleaf是⾯向Web和独⽴环境的现代服务器端Java模板引擎,能够处 理HTML,XML,JavaScript,CSS甚⾄纯⽂本。
Thymeleaf旨在提供⼀个优雅的、⾼度可维护的创建模板的⽅式。为了实 现这⼀⽬标,Thymeleaf建⽴在⾃然模板的概念上,将其逻辑注⼊到模板 ⽂件中,不会影响模板设计原型。这改善了设计的沟通,弥合了设计和 开发团队之间的差距。
Thymeleaf从设计之初就遵循Web标准——特别是HTML5标准 ,如果需要,Thymeleaf允许您创建完全符合HTML5验证标准的模板。
1、导包
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
2、在HTML页面中添加Thymeleaf语法支持
1、HTML属性
Thymeleaf封装了所有的HTML属性,以【th:】开头,后跟上属性名称,th:xxx,大部分Thymeleaf属性 中都可以使用表达式来完成需求。
th:value -> 给value属性赋值
th:text -> 给HTML标签中添加文本,会把字符原样输出
th:utext -> 给HTML标签中添加文本,会把字符中的特殊字符转义
th:if -> 判断
th:each -> 遍历,和th:text或th:value一起使用
th:object -> 引入对象/声明变量,和*{}一起使用
th:attr -> 替换属性
th:fragment -> 定义引入内容
th:insert -> 引入其他页面内容,将被引用的模板片段插⼊到自己的标签体中
th:replace -> 引入其他页面内容,将被引用的模板片段替换掉自己
th:incloud -> 引入其他页面内容,类似于 th:insert,⽽不是插⼊⽚段,它只插⼊此⽚段的内容。
Thymeleaf 3.0 之后不再推荐使⽤ th:include.
2、标准表达式语法
简单表达式
变量表达式:${}
从环境的上下文中获取信息,比如:session、request、ModelAndView,可以理解为JSP中的${};
modelAndView.addObject("msg", "hello");
<h1 th:text="${msg}">h1>
选择表达式:*{}
一般搭配th:object使用,用于获取指定内容
modelAndView.addObject("student", stdent);
<div th:object="${student}">
<p th:text="*{name}">p>
<p th:text="*{age}">p>
<p th:text="*{sex}">p>
div>
信息表达式:#{}
常用于获取properties配置中的值,可以用于国际化操作
连接表达式:@{}
设置连接/路径信息,比如静态资源路径,超链接;
<a th:href="@{https://www.baidu.com}">百度一下a>
<img th:src="@{/img/13.png}">
带参数路径:@{xxx/xxx/(k1=v1,k2=v2...)}
片段表达式:~{}
引入其他页面信息字面量
字面量
普通字符: 'one text', 'Another one!' ...
数字: 0, 34, 3.0, 12.3 ...
布尔: true, false
空对象: null
文字令牌: one, sometext, main, ...
文字令牌只支持字母、数字、and、括号[]、点.、横杠-、下划线_
不支持空格逗号等。
<p th:text="${'one text'}">
<p th:text="${110}">
<p th:text="${true}">
<p th:text="${null}">
<p th:text="${abc}">
字符操作
字符拼接:+
字符替换:|The name is ${name}|
在不使用加号拼接时,需要使用竖线包围
算法运算符
数学运算符:+, -, *, /, %
负数:-
布尔运算符
and、or、!、not
比较运算符
比较运算符:>, <, >=, <= (gt, lt, ge, le)
等值运算符:==, != (eq, ne)
条件运算符
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
value为null或者空字符串时显示默认值
<p th:text="${'1' == '1'} ? '男' : '女'">p>
<p th:text="${'0' == '1'} ? '男' : '女'">p>
特殊字符
无操作:_
<p th:text="${18 < 18} ? '未成年' : _">p>
<p th:text="${20 < 18} ? '未成年' : _">p>
3、常用功能
单对象取值
<div th:object="${student}">
<p th:text="*{name}">p>
<p th:text="*{pass}">p>
<p th:text="*{sex}">p>
<p th:text="*{age}">p>
div>
遍历集合以及判定
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<table>
<thead>
<tr>
<th>snoth>
<th>snameth>
<th>passth>
<th>ssexth>
<th>birthdayth>
<th>del_flgth>
<th>操作th>
tr>
thead>
<tbody>
<tr th:each="map:${list}">
<td th:text="${map.sno}">1000td>
<td th:text="${map.sname}">tomtd>
<td th:text="${map.pass}">123456td>
<td th:text="${map.ssex == '1' ? '男' : '女'}">男td>
<td th:text="${map.birthday}">2020-01-01td>
<td th:if="${map.delFlg} == '1'">显示状态td>
<td th:if="${map.delFlg} == '0'">删除状态td>
<td>
<a href="" th:href="@{/stu/query/(user=${map.sname},pass=${map.pass},sno=${map.sno})}">修改
a>
<a href="" th:href="@{/stu/query/(user=${map.sname},pass=${map.pass},sno=${map.sno})}">删除
a>
td>
tr>
tbody>
table>
body>
html>
引入公共内容
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div style="background-color:red;" th:fragment="top">
这里是头信息的导航
div>
<div style="background-color:blue;" th:fragment="bottom">
域名的备案信息
div>
body>
html>
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div th:insert="~{top :: top}">div>
<div th:replace="~{top :: bottom}">div>
body>
html>
1、/**
静态资源(html、css、js)映射规则
SpringBoot默认提供的存放静态资源的路径:
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
"/"
2、webjars/**
去classpath:/META-INF/resources/webjars/目录下找
https://www.webjars.org/
org.webjars
jquery
3.4.1
http://localhost:8080/webjars/jquery/3.4.1/jquery.js
3、欢迎页
可以将index.html页面放到以下任意一个路径即可。如果以下路径中有多个index.html找到一个就停 止。
"classpath:/META-INF/resources/"
"classpath:/resources/"
"classpath:/static/"
"classpath:/public/"
4、更换启动图标
在classpath目录下创建banner.txt即可
http://patorjk.com/software/taag
http://www.network-science.de/ascii/
5、更换浏览器图标
将自定义的图标重命名favicon.ico,然后放到资源文件夹(resource/static/public)下,重启服务
器即可。
表达式
秒 分 时 日 月 星期 年(可以为空)
第一位:表示秒,取值0-59
第二位:表示分,取值0-59
第三位:表示小时,取值0-23
第四位:日期天/日,取值1-31
第五位:日期月份,取值1-12
第六位:星期,取值1-7,星期一,星期二...
注意:1表示星期天,2表示星期一。
第7为:年份,可以留空,取值1970-2099
*:每,如果加载秒上,表示每秒
/:步长,1/5,如果在秒上,表示,从第一秒开始,每5秒执行一次
?:只能用在每月第几天和星期两个域。表示不指定值,当2个子表达式其中之一被指定了值以后,为了避免冲
突,需要将另一个子表达式的值设为“?”
-:表示范围,例如在分域使用5-20,表示从5分到20分钟每分钟触发一次
,:枚举
L:last,表示最后,只能出现在星期和每月第几天域,如果在星期域使用1L,意味着在最后的一个星期日触
发。
W:表示有效工作日(周一到周五),只能出现在每月第几日域,系统将在离指定日期的最近的有效工作日触发事
件。注意一点,W的最近寻找不会跨过月份
LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五
#:用于确定每个月第几个星期几,只能出现在每月第几天域。例如在1#3,表示某月的第三个星期日
---------------------------------------------------------------------------------
-------------------------------
eg:
* * * * * * -> 每秒执行
0 0 2 * * ?-> 每天凌晨两点执行
生成表达式:http://qqe2.com/cron
1、编写一个定时任务类
@Component // 把这个类交给spirng管理
public class MyQuartz {
@Scheduled(cron="1,5,10 * * * * ?")// 定时任务的表达式
public void doIt(){
System.out.println(new Date());
}
}
2、启动类上开启定时任务
@EnableScheduling // 开启定时任务
1、启动类开启事务开关
@EnableTransactionManagement // 开启事务开关
2、在需要添加事务的方法上添加@Transactional
1、创建拦截器类,继承HandlerInterceptorAdapter,重写方法(根据自己业务需求)
@Component
public class MyInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器执行");
}
}
2、编写一个配置类,实现WebMvcConfigurer,配置自定义拦截器,添加到组件中
@Configuration // 告诉spring我是一个配置类
public class MvcConfig implements WebMvcConfigurer {
@Resource
MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 将自定义的拦截器添加到spring中
// addPathPatterns():拦截请求
// excludePathPatterns(): 黑名单
registry.addInterceptor(myInterceptor).addPathPatterns("/**/*");
}
}
// 在老版本中要继承WebMvcConfigurerAdapter,重写addInterceptors()方法
随着技术发展,JSP的局限性越发突出,为了迎合前后端分离的发展,SpringBoot默认不支持 JSP。但是一些需求下还可能会使用到JSP。
1、添加tomcat的场景启动器
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-tomcatartifactId>
<scope>providedscope>
dependency>
2、在启动类中覆盖原有的内置的tomcat,需要继承SpringBootServletInitializer,重写configure方法
@SpringBootApplication
public class MainApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilderbuilder) {
return builder.sources(MainApplication.class);
}
}