Spring Boot 入门
1、Spring Boot 简介
简化Spring应用开发的一个框架
整个Spring技术栈的一个大整合
J2EE开发的一站式解决方案
2、微服务
2014,martin fowler
微服务:架构风格
一个应用应该是一组小型服务;可以通过HTTP的方式进行互通
单体应用:ALL IN ONE
微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元
3、环境准备
Jdk 1.8
Maven 3.3.9
Idea开发工具
SpringBoot 1.5.9.RELEASE
4、SpringBoot的HelloWorld程序
一个功能:浏览器发送hello请求,服务器接受请求并处理,响应
HelloWorld字符串
(1)创建Maven工程(jar)
(2)导入SpringBoot相关的依赖
(3)编写一个主程序,启动Spring Boot应用
(4)编写一个Controller,必须在主程序的子包内
(5)运行主程序的main方法进行测试
(6)简化部署
1、导入插件
2、运行package命令,进行打包
3、在dos命令中,输入:java -jar 文件名,运行程序
5、HelloWorld探究
(1)POM文件
1、父项目
它的父项目是:
它来真正管理Spring Boot应用里面的所有依赖
也叫Spring Boot的版本仲裁中心:以后我们导入依赖默认是不需
要写版本,(没有在spring-boot-dependencies里面管理的
依赖还是要写)
2、启动器
帮我们导入了web模块正常运行所依赖的组件
spring-boot-starter:spring-boot场景启动器
SpringBoot将所有的功能场景都抽取出来,做成一个个的
starters(启动器),只需要在项目中引入这些starters相关场景的所有依赖都会导入进来,,要用什么功能就导入什么场景的启动器。
(2)主程序类,主入口类
@SpringBootApplication:标注在某一个类上,说明这个类
SpringBoot的主配置类,运行这个类的
main方法来启动SpringBoot应用
@SpringBootConfiguration:标注在某个类上,表示这是一个
SpringBoot的配置类
@Configuration:配置类上来标注这个注解
配置类—-配置文件,配置类也是容器中的组件@Component
@EnableAutoConfiguration:开启自动配置功能
以前我们需要配置的东西,SpringBoot帮我们自动配置。
该注解告诉SpringBoot开启自动配置功能,这样自动配
置才能生效。
1、@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class) @Import是Spring的底层注解,给容器中导入组件,组
件由AutoConfigurationPackages.Registrar类指定
作用:将主配置类(@SpringBootApplication标注的类)
的所在包及下面所有子包里面的所有组件扫描到
Spring容器
2、@Import(EnableAutoConfigurationImportSelector.class)
给容器中导入组件。
EnableAutoConfigurationImportSelector:将所有需要导入
的组件以全类名的方式返回,这些组件就会被添加
到容器中。
会给容器中导入非常多的自动配置类(xxAutoConfiguration)
,就是给容器中导入这个场景需要的所有组件,并配置好这
些组件。有了自动配置类,免去了我们手动编写配置注入功
能组件等的工作。
方法: SpringFactoriesLoader.loadFactoryNames(
EnableAutoConfiguration.class, ClassLoader beanClassLoader)
作用:SpringBoot在启动的时候从类路径下的META-INF/
spring.factories中获取EnableAutoConfiguration指
定的值,将这些值作为自动配置类导入到容器中,自动
配置类就生效,帮我们进行自动配置工作。
J2EE的整体整合解决方案和自动配置都在spring-boot-
autoconfigure/org.springframework.boot.autoconfigure
6、使用Spring Initializer快速创建Spring Boot项目
选择我们需要的模块,向导会联网创建SpringBoot项目;
默认生成的SpringBoot项目有如下几个特点:
1、主程序已经生成好了,只需要自己编写业务逻辑即可
2、resource文件夹中目录结构:
static:保存所有静态资源,js,css,image
templates:保存所有的模版页面(SpringBoot默认jar包
使用内嵌的Tomcat,默认不支持jsp页面)可
以使用模版引擎(freemarker,thymeleaf)
application.properties:SpringBoot应用的配置文件,可
以修改一些默认设置
一、 Spring Boot 配置
1、配置文件
SpringBoot使用一个全局的配置文件,配置文件名是固定的
application.properties
application.yml
优先级:properties 》yml
配置文件的作用:修改SpirngBoot自动配置的默认值,SpringBoot在底
层给我们配置自动配置好的,如果需要自行修改,就在配置文件中修改
YAML(简称:yml):一种标记语言,又不是一个标记语言,以数据为中心,
比json,xml更适合做配置文件
2、YAML语法
(1)基本语法
key:(空格)value 表示一对键值对(空格必须有)
以空格的缩进来控制层级关系;只要是左对齐的一列数据都是同一层级 属性和值都是大小写敏感
(2)值(value)的写法
字面量:普通的值(数字,字符串,布尔)
key: value:字面直接来写
字符串摩恩不用加上单引号或者双引号
单引号:会转义字符串里面的特殊字符,特殊字符最终只是一个
普通的字符串数据
Name: “zhangsan \n lisi”: zhangsan \n lisi
双引号:不会转义字符串里面的特殊字符,特殊字符会作为本身
想表示的意思
Name: “zhangsan \n lisi”: zhangsan 换行 lisi
对象、Map(属性和值)(键值对):
k: v:在下一行来写对象的属性和值的关系,注意缩进
对象还是k: v的方式
例子:
Friends:
lastName: zhangsan
age: 20
行内写法:friends: {lastName: zhangsan,age: 18}
数组(List,Set):
用- 值表示数组中的一个元素
例子:
Pets:
- cat
- dog
- pig
行内写法:pets: [cat,dog,pig]
3、配置文件注入
(1)编写配置文件
第一种:yml配置文件
person:
age: 18
name: zhangsan
dog:
name: 小狗
age: 2
maps:
k1: v1
k2: v2
list:
- cat
- set
birth: 2017/12/12
boss: false
第二种:properties配置文件
person.age=18
person.birth=2017/12/12
person.name=张三
person.boss=true
person.maps.k1=v1
person.maps.k2=v2
person.list=a,b,c
person.dog.name=小狗
person.dog.age=2
(2)javabean(提供成员变量和set/get/toString方法)
目的:将配置文件中配置的每一个属性的值,映射到这个对象中
A、第一种方法:
在类上配置两个注解:
@ConfigurationProperties
作用:告诉SpringBoot将本类的所有属性和配置文件中相关
的配置进行绑定。默认从全局配置文件获取值
属性:perfix=””
属性内的值全部必须为小写
配置文件中哪个属性的下面所有属性进行一一映射
前提:javabean必须是Spring的容器,才能使用该功能
解决:在javabean类上配置@Component
B、第二种方法:
在属性上使用@Value注解
该注解的功能类似
支持:#{SpEL表达式},字面量(字符串,数字,布尔值等)
${key}(从环境变量,配置文 件中获取)
(3)往pom.xml中导入依赖
导入该配置文件处理器依赖,配置文件进行绑定就会有提示。
(4)properties配置文件文件乱码问题
Idea使用的是utf-8
Properties文件使用的ASCII码
解决:修改properties文件的编码
(5)@Value和@ConfigurationProperties获取值比较
@Value:一个个指定;不支持松散语法绑定;不支持SpEL;
不支持JSR303数据校验;不支持复杂类型封装
@ConfigurationProperties:可以批量注入配置文件中的属性;支持松散
语法绑定;支持SpEL;支持复杂类型封装
支持 303数据校验(@Validated)
松散语法:
person.firstName : 标准形式
person.first-name : 用-代表后首字母大写
person.firstname :用代表后首字母大写
PERSONFIRST_NAME : 大小写不区分,用
如果说,只是在某个业务逻辑中获取配置文件的值,使用@Value
如果说,javabean和配置文件进行映射,直接使用@ConfigurationProperties
4、@PropertySource和@ImportResource
(1)@PropertySource
作用:加载指定的配置文件(properties,xml,yml)
使用的位置:类上
(2)@ImportResource
作用:导入Spring的配置文件,让配置文件的内容生效
SpringBoot项目不会自动加载Spring的配置文件。想让Spring配置文件
的生效,就要将@ImportResource标注在一个配置类上。
例子:
@ImportResource(locations = {“classpath:bean.xml”})
(3)SpringBoot推荐给容器中添加组件的方式:推荐使用全注解的方式
配置类====Spring配置文件
在配置类中编写带有的返回值的方法,并在方法上加上@Bean
@Bean:将方法的返回值添加到容器中,组件的id就是方法名。
该注解就是
5、配置文件占位符
(1)配置文件可以使用随机数
${random.uuid} ${random.int()}
(2)可以使用之前配置过的属性值
${person.name}
(3)可以添加默认值
${person.name:张三} 如果找不到person.name值,就使用“张三”
6、Profile
包括:dev(开发环境),prod(生产环境)
(1)多profile文件格式
在编写主配置文件的时候,文件名可以是application-{profile}.properties
/yml
默认使用application.properties/yml
(2)yml支持多文档块方式
用“—-”分开。
(3)激活指定profile
第一种方法:在配置文件中指定要激活的profile
spring.profiles.active=dev/prod
第二种方法:命令行的方式
A、运行时添加命令:—spring.profiles.active=dev/prod
B、先将项目打包package,然后在cmd窗口中,
java –jar 文件名 —spring.profiles.active=dev/prod
优先级:命令行 》配置文件中指定
第三种方法:虚拟机参数(VM options)
—Dspring.profiles.active=dev/prod
7、配置文件的加载位置
SpringBoot启动会自动扫描以下位置的application.properties或者
application.yml文件作为SpringBoot的默认配置文件。
优先级由高到低,高优先配置覆盖低优先配置:
项目下/config/application.properties,yml
项目下/application.properties,yml
classpath:application.properties,yml
classpath:application.properties,yml
还可以在项目打包后,可以使用命令:spring.config.location,启动项目的时
候指定配置文件的新位置,指定的配置文件和默认加载的这些配置文件共同
起作用。
代码实现:04-SpringBoot-Config-02项目
8、外部配置加载顺序
SpringBoot也可以从以下位置加载配置,优先级从高到低,高优先级的配置
覆盖低优先级的配置,所有的配置会形成互不配置。
1、命令行参数
java –jar 文件名 –server.port=8090 —server.context.path=/abc
多个配置用空格分开;—配置项=值
2、来自java:comp/env的JNDI属性
3、java系统的属性(System.getProperties())
4、操作系统环境变量
5、RandomValuePropertySource配置的random.属性值
由jar包外向jar包内进行寻找:
优先加载带profile:
6、jar包外部的application-{profile}.properties/yml(带spring.profile)配置文
件
7、jar包内部的application-{profile}.properties/yml(带spring.profile)配置文
件
再来加载不带profile:
8、jar包外部的application-{profile}.properties/yml(不带spring.profile)配置
文件
9、jar包外部的application-{profile}.properties/yml(不带spring.profile)配置
文件
10、@Configuration注解类上的@PropertySource
11、通过SpringApplication.setDefaultProperties指定的默认属性
9、自动配置原理
配置文件能写什么?怎么写?配置文件的属性参照:
属性参照
自动配置原理:
1、SpringBoot启动的时候加载主配置类,开启了自动配置功能
@EnableAutoConfiguration
2、@EnableAutoConfiguration作用:
利用AutoConfigurationImportSelector给容器中导入一些组件 详细可以查看getAutoConfigurationEntry ()方法的内容:
List
(annotationMetadata,attributes);获取后选的配置
1、SpringFactoriesLoader.loadFactoryNames()
2、扫描所有jar包,类路径下 META-INF/
spring.factories
3、把扫描到的这些文件的内容包装成properties对
象
4、从properties中获取到EnableAutoConfiguration
.class类(类名)对应的值,然后把它们添加到
容器中
将类路径下META-INF/spring.factories里配置的所有
EnableAutoConfiguration的值加入到容器中:
每一个这样的xxxAutoConfiguration类都是容器中的一个组件,
都会加入到容器中,用它们来做自动配置。
3、每一个自动配置类进行自动配置功能
4、以HttpEncodingAutoConfiguration(Http编码自动配置)
为例解释自动配置原理:
//表示这是一个配置类
@Configuration
//启用指定类的ConfigurationProperties功能;将配置文件中
对应的值和HttpProperties绑定起来;并把HttpProperties加
入到ioc容器中
@EnableConfigurationProperties(HttpProperties.class)
//Spring底层@Conditional注解,作用:根据不同的条件,如
果满足指定的条件,整个配置类里面的配置就会生效。
此处的条件:判断当前应用是否时Web应用
@ConditionalOnWebApplication(type =
Conditional0nWebApplication.Type.SERVLET)
//判断当前项目有没有CharacterEncodingFilter类,SpringMVC
中进行乱码解决的过滤器
@ConditionalOnClass(CharacterEncodingFilter.class)
//判断配置文件中是否存在某个配置:spring.http.encoding.
enabled;如果不存在,判断也成立。
即使不配置,也是默认生效的。
@ConditionalOnProperty(prefix = “spring.http.encoding”,
value = “enabled”, matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
//已经和SpringBoot的配置文件映射了
private final HttpProperties.Encoding properties;
//只有一个有参构造器的情况下,参数的值就会从容器
中拿
public HttpEncodingAutoConfiguration(HttpProperties
properties)
{
this.properties = properties.getEncoding();
}
//给容器中添加组件,这个组件的某些值需要从
properties中获取
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new
OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.
shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.
shouldForce(Type.RESPONSE));
return filter;
}
总结:根据不同的条件,判断这个配置类是否生效?一旦这个配
置类生效了,这个配置类就会给容器中添加各种组件,这
些组件的属性是从对应的properties类中获取的。这些类
里面的每一个属性又是和配置文件绑定的。
5、所有在配置文件中能配置的属性都是在xxxProperties类中封装
配置文件能配置什么就参照某个功能对应的这个属性类
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = “spring.http”)
public class HttpProperties {
6、精髓:
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有SpringBoot默认写好的自动配
置类
3、我们再来看这个自动配置类中到底配置了哪些组件(只要我
们要用的组件有,我们就不需要配置了。)
4、给自动配置类添加组件的时候,会从properties类中获取某
些属性,我们就可以在配置文件中指定这些属性的值。
xxxAutoConfiguration:自动配置类
给容器中添加组件
xxxProperties:封装配置文件中相关属性
10、@Conditional派生注解(Spring注解版原生的@Condition)
作用:必须是@Conditional指定的条件成立,自动配置类才会生效,才能
给容器中添加组件,配置里面的所有内容才生效。
自动配置类在一定条件下才能生效。怎么知道哪些自动配置类生效?
可以通过启用debug=true属性,来让控制台打印自动配置报告。 报告会给出:
1、Positive matches:(自动配置类启用的)
2、Negative matches:(没有匹配成功的自动配置类)
二、 Spring Boot与日志
1、日志框架
市面上的日志框架:
JUL,JCL,jboss-loging,logback,log4j,log4j2,slf4j
方法:左边选一个门面(抽象层),右边选一个实现。
选择:日志门面:SLF4j 日志实现:Logback
SpringBoot:底层是Spring框架,Spring框架默认使用JCL
SpringBoot选用SLF4j和Logback。
2、SLF4j使用
(1)如何在系统中使用SLF4j
以后开发的时候,日志记录方法的调用,不应该直接调用日志的实现类,而
是调用日志抽象层里面的方法。
第一步:导入slf4j和logback的jar包
第二步:调用,查看slf4j的官方文档https://www.slf4j.org/manual.html
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info(“Hello World”);
}
}
每一个日志的实现框架都有自己的配置文件,使用slf4j以后,配置文件还
是做成日志实现框架的配置文件。
3、遗留问题
开发a(slf4j+logback):Spring(commons-loggin),hibernate(jboss-logging),xxx
统一日志记录,即使是别的框架和我一起统一用slf4j进行输出。
如何将系统中所有的日志都统一到slf4j:
1、将系统中的其它日志框架先排除出去
2、用中间包来替换原来的日志框架
3、我们导入slf4j其它实现
4、SpringBoot的日志关系
SpringBoot使用以下依赖来做日志:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <version>2.1.1.RELEASE</version> <scope>compile</scope> </dependency>
jul-to-slf4j:替换java.utils.logging
总结:
1、SpirngBoot底层也是使用slf4j+logbackk的方式进行日志记录
2、SpringBoot也把其它的日志都替换成了slf4j
3、使用了中间替换包
4、如果要引入其它其它框架,一定把这个框架默认的日志依赖移除
(1)使用的是SpringBoot2.1.1版本,Spring的版本是5.1.3
(2)Spring中没有默认导入commons-logging依赖。
(3)SpringBoot能自动适配所有日志,而且底层使用
slf4j+logback的方式记录日志,引入其它框架的时候,只需
要把这个框架依赖的日志包排除掉。
5、日志使用
(1)自定义日志
//记录器
Logger logger= LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
/**
可以调整日志的输出级别
/
//跟踪轨迹
logger.trace(“trace日志”);
//调试
logger.debug(“debug日志”);
//自定义信息
logger.info(“info日志”);
//警告
logger.warn(“warn日志”);
//错误,捕获异常
logger.error(“error日志”);
}
(2)设置日志的输出级别
SpringBoot默认的日志输出级别为info。
在配置文件中修改:(指定哪个包的日志输出级别)
logging.level.包名.包名=trace,info,
(3)其它设置
logging.file:可以指定当前项目的相对路径,也可是具体的磁盘路径
logging.path:默认输出到spring.log文件。路径是相对于项目所在的磁盘中
当两者都指定时,logging.file起作用。
logging.pattern.console:在控制台输出的日志的格式
logging.pattern.file:指定文件中日志输出的格式
6、指定日志配置文件
指定了自己的日志配置文件,SpringBoot就不会用默认的配置文件。
logback.xml:直接被日志框架识别。
SpirngBoot推荐我们命名时,带有spring扩展,例如:logback-spring.xml。
logback-spring.xml:日志框架不直接加载日志的配置项,由SpirngBoot加载
可以指定某段配置只在某个环境下生效。
7、切换日志框架
SpringBoot默认使用slf4j+logback来实现日志功能。
需求:改成slf4j+log4j
方法1:(这种方法不使用)
第一步:排除掉logback日志包。
第二步:导入log4j和slf4j的适配包,slf4j-log4j12
第三步:必须要有log4j的配置文件
方法2:
第一步:将spring-boot-starter-logging依赖移除
第二步:导入下面的任意一个依赖
四、Spring Boot与Web
1、SprirngBoot对静态资源的映射规则
(1)所有/webjars/ : 都是去classpath:/META-INF/resources/webjars寻找
webjars:以jar包的形式引入静态资源
(2)/ :访问当前项目的任何资源,(静态资源的文件夹)
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/ : 当前项目的根路径
例子:localhost:8080/abc.html 去静态资源文件夹找
(3)欢迎页:静态资源文件夹下的所有index.html页面,被/映射
例子:localhost:8080 找静态资源文件夹内的index.html
(4)所有的/favicon.ico 都是在静态资源文件下找
(5)通过配置文件修改静态资源文件夹的位置
Spring.resource.static.location=
是数组,想配置多个,直接用“,” 隔开
2、模版引擎
Jsp,Velocty,Freemarker,Thymeleaf
SpringBoot推荐的模版引擎是Thymeleaf。语法简单,功能强大。
第一步:引入Thymeleaf(默认3.0.11版本)
第二步:Thymeleaf使用和语法
只要我们把HTML页面放在classpath:/templates/,thymeleaf会自动渲染
使用:
(Controller方法的返回也就是templates文件夹内html页面的名字)
第一步:在html页面导入thymeleaf名称空间
xmlns:th=http://www.thymeleaf.org
第二步:使用thymeleaf的语法
<div th:text=”${hello}”></div>
语法规则:
(1)th:任意html属性
作用:来替换原生属性的值
例如:th:text 改变当前元素的文本内容
(2)表达式
Simple expressions: (表达式语法)(最重要)
Variable Expressions: ${…} 获取变量值,OGNL表达式
1、 获取对象的属性
2、 调用方法,可传参
3、 可以使用内置的基本对象
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest
object.
#response : (only in Web Contexts) the HttpServletResponse
object.
#session : (only in Web Contexts) the HttpSession object. #servletContext : (only in Web Contexts) the ServletContext
object.
4、 可以使用内置的工具对象
#execInfo : information about the template being processed. #messages : methods for obtaining externalized messages inside
variables expressions, in the same way as they
would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs Page 20 of 106 #conversions : methods for executing the configured conversion
service (if any).
#dates : methods for java.util.Date objects: formatting,
component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar
objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith,
prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or
collections.
#ids : methods for dealing with id attributes that might be
repeated (for example, as a result of an iteration).
Selection Variable Expressions: {…} 选择表达式,功能和${}一样
补充功能:配置th:object使用,可以代替上文的对象
Message Expressions: #{…} 获取国际化内容
Link URL Expressions: @{…} 定义url
/ 代表当前项目地址 http://localhost:8080/项目
Fragment Expressions: ~{…} 片段表达式
Literals (字面量)
Text literals: ‘one text’ , ‘Another one!’ ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal tokens: one , sometext , main ,…
Text operations: (文本操作)
String concatenation: +
Literal substitutions: |The name is ${name}|
Arithmetic operations: (数学运算)
Binary operators: + , - , * , / , %
Minus sign (unary operator): -
Boolean operations: (布尔运算)
Binary operators: and , or
Boolean negation (unary operator): ! , not
Comparisons and equality: (比较运算)
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne )
Conditional operators: (条件运算)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
Special tokens:
No-Operation: _ (无操作)
(3)行内写法
使用th标签时,想在html标签中间填写文本内容,使用:[(..)]
3、SpringMVC的自动配置原理
SpringBoot对web的所有自动配置都在org.springframework.boot.
autoconfigure.web包中。
(1)WebMvcAutoConfiguration类中的自动配置:
Inclusionof
ContentNegotiatingViewResolver
and BeanNameViewResolver
beans.· 自动配置了ViewResolver(视图解析器,根据方法的返回值得到视图对象View,视图对象决定如何渲染(转发?重定向?))
· ContentNegotiatingViewResolver:组合所有的视图解析器
· 如何定制:我们可以自己给容器添加一个视图解析器,ContentNegotiatingViewResolver自动将其组合进去
· Support for serving static resources, including support for WebJars (covered later in this document)).
· 静态资源文件夹
· Webjars
· Automatic registration of
Converter
, GenericConverter
, and Formatter
beans.· 自动注册了Converter ,GenericConverter,Formatter
· Converter:转换器,类型转换使用
· Formatter:格式化器;2017-12-12==Date
· 条件:在文件中配置日期格式化的规则(spring.mvc.date-format)
· 配置后,才会返回日期格式化组件DateFormatter
· 定制:将自己实现的格式化器/转换器放在容器中即可
· Support for
HttpMessageConverters
(covered later in this document).· HttpMessageConverters:SpringMVC用来转化HTTP请求和响应的;
· HttpMessageConverters是从容器中确定,获取所有的HttpMessageConverter
· 定制:将自己实现的HttpMessageConverter放入容器中
· Automatic registration of
MessageCodesResolver
(covered later in this document).
· 定义错误代码生成规则的
· Static
index.html
support.· 静态首页访问
· Custom
Favicon
support (covered later in this document).· Favicon.ico
· Automatic use of a
ConfigurableWebBindingInitializer
bean(covered later in this document).· 首先是容器中获取ConfigurableWebBindingInitializer
· 如果没有,就调用父类的方法来创建一个新的
· 作用:初始化WebDataBinder(数据绑定器)
(2)扩展SpringMVC
方法:编写一个配置类@Configuration,实现类型为WebMvcConfigurer接口,不能标注@EnableWebMvc。实现自己想要实现的方法即可。
需求:发送/peng请求,跳转到suucess页面
好处:只是为了来到success页面,没必要写多个方法
代码实现:
原理:
1、WebMvcAutoConfiguration是springmvc的自动配置类
2、在做其它自动配置时会导入@Import(EnableWebMvcConfiguration.class))
3、EnableWebMvcConfiguration继承DelegatingWebMvcConfiguration
4、DelegatingWebMvcConfiguration类的内容:
//从容器中获取所有的WebMvcConfigurer
@Autowired(required = false)
public void setConfigurers(List
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
//一个参考实现:将所有的WebMvcConfigurer相关配置都来一起调用
//@Override
//public void addViewControllers(
ViewControllerRegistry registry){
//for (WebMvcConfigurer delegate :
this.delegates)
{
//delegate.addViewControllers(registry);
//}
//}
}
}
5、容器中所有的WebMvcConfigurer都会一起起作用
6、因此,我们的配置类也会被调用
效果:SpringMVC的自动配置和我们的扩展配置都会起作用
(3)全面接管SpringMVC(不推荐)
概述:也就是SpringBoot对SpringMVC的所有自动配置都不需要了,所有的SpringMVC自动配置都失效了,所有的都是我们自己配置的。
方法:编写一个配置类@Configuration,类型为WebMvcConfigurer并标注@EnableWebMvc
原理:(解释@EnableWebMvc让自动配置失效了?)
1、@EnableWenbMvc的核心
2、
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3、
4、@EnableWebMvc将WebMvcConfigurationSupport组件导进来,
5、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能
(4)如何修改SpringBoot的默认配置
模式:
(1) SpringBoot在自动配置很多组件的时候,先看容器中用户有没有自己配置,如果有,就用用户配置的。如果没有,就用自动配置的。如果有些组件可以有多个(ViewResolver),就会将用户配置的和默认的组合起来。
(2) 在SpringBoot中会有非常多的xxConfigurer,帮助我们进行扩展配置。
(3) 在SpringBoot中会有很多的xxxCustomizer,帮助我们进行定制配置。
4、项目1:RestfulCURD
(1)引入thymeleaf依赖
(2)扩展SpringMVC,将访问路径“/“,”/login.html”映射成登陆界面
login.html。
(3)国际化
Springmvc原来的做法:
1、编写国际化配置文件
2、使用ResourceBundleMessageSource管理国际化资源文件
3、在页面使用fmt:message取出国际化内容
SpringBoot的做法:
1、编写国际化配置文件,抽取页面需要显示的国际化消息
2、SpringBoot自动配置好了管理国际化资源文件的组件
在配置文件中修改国际化配置文件的基础名为login。
(可带包名,用“.”分隔)
Spring.messages.basename=i18n.login
3、去页面获取国际化的值
使用thymeleaf的#{}来获取国际化信息。
4、实现点击按钮,页面进行切换国际化
原理:SpringBoot自动配置Springmvc默认的国际化
Locale(区域信息对象),LocaleResolver(获取区
域信息对象)
自定义LocaleResolver:
第一步:自定义一个类,实现resolveLocale接口
第二步:将自定义的LocaleResolver添加到容器中
注意:方法名必须是localeResolver
(4)实现登陆功能和拦截器
开发期间模版引擎页面修改以后,要实时生效:
1、禁用模版引擎缓存
spring.thymeleaf.cacahe=false
2、页面修改完成以后,crt+f9,重新编译
1、编写登陆功能的Controller方法
视图映射:
2、登陆成功,转发到成功页面
3、登陆失败,跳转到登陆页面
4、编写拦截器进行登陆检查(和springmvc一样)
第一步:自定义类,并实现HandlerInterceptor接口,完善三个
方法。
preHandle方法:目标方法执行之前
返回true:放行请求
返回false:拦截请求
第二步:修改登陆功能的controller方法,将用户保存到session
第三步:配置拦截器,将拦截器加入到springmvc中
(5)CRUD-员工列表
实验要求:
(1)RestfulCRUD:CRUD满足Rest风格
URI:/资源名称/资源标识 HTTP请求方式区分对资源CRUD操作
普通CRUD | RestfulCRUD | |
---|---|---|
查询 | getEmp | emp—-GET |
添加 | addEmp?xxx | emp—-POST |
修改 | updateEmp?id=xxx | emp/{id}—-PUT |
删除 | deleteEmp?id=xxx | emp/{id}—-DELETE |
(2)实验请求架构:
请求URI | 请求方式 | |
---|---|---|
查询所有员工 | emps | GET |
查询某个员工 | emp/{id} | GET |
来到添加页面 | emp | GET |
添加员工 | emp | POST |
来到修改页面 | emp/{id} | GET |
修改员工 | emp | PUT |
删除员工 | emp/{id} | DELETE |
(3)员工列表
第一步:thymeleaf公共页面元素抽取(未实现)
抽取公共元素:th:fragement=””
例子:
引用公共元素:th:insert=””
~{templatename::selector} 模版名:选择器
~{templatename::fragmentname} 模版名:片段名
模版名也就是页面的名称,也会使用thymeleaf的前后缀
配置规则。
例子:
三种引入功能片段的th属性:
th:insert 将整个公共片段(包括标签)放入div标签中
th:replace 将声明引入的元素替换为公共片段
th:include 将公共片段里的内容放入div标签中
行内写法:[[~{}]] [(~{})]
第二步:知识点:参数化的片段签名(未实现)
使用(xxx=’XXX’)来传参
第三步:编写查询所有员工的Controller方法和页面
(4)添加员工
第一步:编写跳转到添加页面的Controller方法
第二步:编写添加员工的Controller方法
redirect:表示重定向到一个地址 / :表示当前项目路径
forward:表示转发到一个地址
可以通过配置文件设置spring.mvc.date-format来修改
(5)员工修改
第一步:编写“修改”的链接地址和跳转Controller方法
知识点:@PathVariable(“”) 用来获取地址的变量
第二步:编写put方法的请求
在页面中是不能直接使用put请求的
需要经过以下三步:
(1)SpringMVC中配置HiddenHttpMethodFilter
(SpringBoot自动配置好的)
(2)页面中创建一个post表单
(3)创建一个input项,name=”_method”,值就是我们
指定的请求方式
第三步:编写“修改”的Controller方法
(6)员工删除
第一步:编写“删除”链接的地址
第二步:编写delete请求
不要在按钮中添加表单,这会使页面变得复杂。
应该使用js来完成请求的提交。
知识点:自定义页面元素的属性,并且可以使用thymeleaf
使用:th:attr=”元素名=xxx” xxx可以使用th表达式
第三步:编写“删除”的Controller方法
五、Spring Boot与错误机制
1、错误处理机制
1、SpringBoot默认的错误处理机制
默认效果:
(1)浏览器访问,返回一个错误页面
浏览器发送的请求头:
(2)其它客户端访问,响应json数据
其它客户端发送的请求头:
原理:可以参照ErrorMvcAutoConfiguration类,错误处理的自动配置
给容器添加了以下组件:
1、DefaultErrorAttributes:
2、BasicErrorController:处理默认的/error请求
3、ErrorPageCustomizer
系统出现错误以后来到error请求进行处理(类似
web.xml注册的错误页面规则)
4、DefaultViewResolver
步骤:
一旦系统出现4xx或5xx之类的错误;ErrorPageCustomizer就会
生效(定制错误的响应规则);就会来到/error请求;就会被
BasicErrorController处理;
(1)响应页面:去哪个页面是由DefaultViewResolver解析得到
所有的ErrorViewResolver得到ModelAndView
2、如何定制错误响应
(1)如何定制错误的页面
1、有模版引擎的情况下:
(1)错误页面命名为:error/状态码.html,放在模版引
擎文件夹template内。
(2)可以使用将错误页面的命名统称化:error/4xx.html
也就是所有以4开头的错误,都会来到此页面
优先寻找(1),然后在寻找(2)
(3)页面获取的信息:
timestamp:时间戳
status:状态码
error:错误提示
exception:异常对象
message:异常消息
errors:JSR303数据校验的错误都在这里
(4)获取错误信息,在页面中显示
行内写法:[[${status}]]
2、没有模版引擎,静态资源文件夹内找
3、以上都没有错误页面,默认来到SpringBoot默认的错误
提示页面
(2)如何定制错误的json数据
1、自定义异常处理,返回定制的json数据(没有自适应效果)
浏览器和其它客户端都是响应异常处理方法中设置的
json数据
2、转发到/error
A、浏览器访问时,来到默认的错误提示页面。
B、其它客户端访问时,响应异常类构造函数的异常信息,
而不是异常处理方法中设置的json数据。
3、转发到/error和设置状态码,进行自适应响应效果处理
A、浏览器访问时,来到自己配置的错误提示页面。
B、其它客户端访问时,响应异常类设置的异常信息,而
不是异常处理方法中设置的json数据。
4、将异常处理方法中定制的数据携带出去,自适应响应效果
出现错误以后,会来到/error请求,会被
BasicErrorController处理,响应出去可以获取的数据是由
getErrorAttributes()方法得到(是AbstractErrorController
(ErrorController)的方法);
1、完全来编写一个ErrorController的实现类【或者是编写
AbstractErrorController的子类】
2、页面上能用的数据,或者是返回的json数据都是通过
errorAttributes.getErrorAttributes得到
容器中默认有DefaultErrorAttributes进行数据处理。
自定义ErrorAttributes:
1、编写自定义ErrorAttributes类,继承DefaultErrorAttributes
2、往父类的getErrorAttributes方法的返回值中添加需要的
数据
3、形参webRequest,可以用来获取请求域中的数据
最终的效果:响应是自适应的,通过定制ErrorAttributes改
变返回的内容。
六、Spring Boot与Servlet容器
1、配置嵌入式Servlet容器
SpringBoot默认使用Tomcat作为嵌入式的Servlet容器(Tomcat 9.0.13)
问题:
(1)如何定制和修改Servlet容器的相关配置(适用所有的Servlet容器)
1、在配置文件中,配置和server有关的配置(ServerProperties)
例如:server.port=8082
通用的servlet容器配置:
A、server.xxx
B、server.tomcat.xxx
2、编写一个WebServerFactoryCustomizer
Servlet容器的定制器,来修改Servlet容器的配置
必须加入@Bean注解,添加到容器中。
3、注册Servlet三大组件
三大组件:Servlet,Filter,Listener
原因:由于SpringBoot默认是以jar包的方式启动嵌入
式的Servlet容器来启动SpringBoot应用,没有web.
xml文件,无法像之前一样进行配置
注册类:
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
第一步:编写一个配置类
第二步:编写返回注册类的方法
第三步:方法上必须使用@Bean注解,将注册的添加到
容器中
4、SpringBoot帮我们自动注册SpringMVC的前端控制器:
DispatchServlet
(2)SpringBoot支持的Servlet容器
默认支持:
Tomcat(默认使用):
Jetty(长连接)
在pom.xml中引用:(仿照默认的Tomcat)
Undertow(不支持jsp)
在pom.xml中引用:(仿照默认的Tomcat)
(3)嵌入式Servlet容器自动配置原理
SpringBoot 2.0以上,EmbeddedServletContainerCustomizer
被WebServerFactoryCustomizer替代 。
EmbeddedWebServerFactoryCustomizerAutoConfiguration:嵌入式
的Servlet容器自动配置
我们对嵌入式容器的配置修改是怎么生效的?
第一种:ServerProperties
第二种:WebServerFactoryCustomizer(定制器)
原理:导入了一个后置处理器:
WebServerFactoryCustomizerBeanPostProcessor
自动配置原理的整体步骤:
(1)SpringBoot根据导入的依赖情况,给容器中添加相应的
WebServerFactoryCustomizer,例如:Tomcat
(2)容器中某个组件要创建就会惊动后置处理器:
WebServerFactoryCustomizerBeanPostProcessor
只要是嵌入式的Servlet容器,后置处理器就工作
(3)后置处理器从容器中获取所有的WebServerFactoryCustomizer
(定制器),调用定制器的方法。
(4)嵌入式Servlet容器的启动原理
研究的问题:什么时候创建嵌入式的Servlet容器工厂?什么时候获
取嵌入式的Servlet容器并启动Tomcat?
创建嵌入式的Servlet容器工厂:
(1)SpringBoot应用启动运行run方法
(2)refreshContext(context);SpringBoot刷新IOC容器【创建IOC
容器对象,并初始化容器,创建容器中的每一个组件】;
如果是web应用,创建AnnotationConfigEmbeddedWeb
ApplicationContext。否则,AnnotationConfigApplication
Context。
(3)refresh(context);刷新上一步创建好的IOC容器
(4)onrefresh();web的IOC容器重写了该方法
(5)web的IOC容器会创建嵌入式的Servlet容器,createEmbedd
ServletContainer();
(6)获取嵌入式的Servlet容器工厂:
EmbeddedServletContainerFactory containerFactory=
getEmbeddedServletContainerFactory();从IOC容器中获取 EmbeddedServletContainerFactory组件。默认创建Tomcat (因为默认导入的是Tomcat包)
(7)获取嵌入式的Servlet容器
(8)嵌入式的Servlet容器创建对象并启动
先启动嵌入式的Servlet容器,再将IOC容器中剩下没有创
建出来的对象获取出来。
2、使用外置的Servlet容器
(1)嵌入式的Servlet容器:应用打成可执行的jar
优点:简单,便携
缺点:默认不支持jsp,优化定制比较复杂(使用定制器
WebServerFactoryCustomizer;或者,自己编写嵌入式Servlet容
器创建工厂)
(2)外置的Servlet容器:外部安装Tomcat—应用war包
第一步:创建war工程
第二步:引入tomcat依赖,改为provided
第三步:编写一个类,继承SpringBootServletInitializer,重写configure
第四步:启动服务器就可以用了
(3)原理:
jar包:执行SpringBoot 主类的main方法,启动IOC容器,创建嵌
入式的Servlet容器
war包:启动服务器,服务器启动SpringBoot应用
【SpringBootServletInitializer】,启动IOC容器
(4)步骤:
七、Spring Boot与Docker
1、Docker简介
Docker是一个开源的应用容器引擎,支持将软件编译成一个镜像,然后在镜
像中对各种软件做好配置,将镜像发布出去,其它使用者可以直接使用这个
镜像。运行中的镜像称为容器,容器的启动是非常快速的。
2、Docker核心概念
Docker主机:安装了Docker程序的机器(Docker直接安装在操作系统上)
Docker客户端:连接Docker主机进行操作
Docker仓库:用来保存各种打包好的软件镜像
Docker镜像:软件打包好的镜像,放在Docker仓库中
Docker容器:镜像启动后的实例称为一个容器,是独立运行的一个或一组应
用
3、Docker使用步骤
第一步:安装Docker
第二步:去Docker仓库找到软件对应的镜像
第三步:直接使用Docker运行这个镜像,这个镜像就会生成一个Docker
容器
第四步:对容器的启动、停止就是对软件的启动、停止
4、在linux虚拟机上安装Docker
详细步骤,参考网址Docker安装
5、Docker镜像操作的常用命令
搜索镜像:docker search 镜像名
下载镜像:docker pull 镜像名:tag
tag是可选的,tag表示标签,多为软件的版本,默认是latest
查看所有镜像:docker images
删除镜像:docker rmi image-id
6、容器操作
软件镜像—运行镜像—产生一个容器
步骤:
A、 搜索镜像 docker search tomcat
B、下载镜像 docker pull tomcat
C、 启动容器 docker run –name 自定义名 –d 镜像名:tag
D、 查看运行中的容器 docker ps
E、 停止运行中的容器 docker stop 容器id
F、 查看所有的容器 docker ps –a
G、 启动容器 docker start 容器id
H、 删除一个容器(停止状态) docke rm 容器id
I、 启动一个做了端口映射的容器
Docker run –d –p 主机端口:容器内部端口 镜像名:tag
-d:代表后台运行
-p:代表将主机的端口映射到容器的一个端口
J、 防火墙设置
查看防火墙状态:service firewalld status
临时关闭防火墙:service firewalld stop
K、 查看容器日志
docker logs 容器名/容器id
7、Docker安装mysql
命令:docker pull mysql
启动:
(1)
docker run —name 自定义名 -e MYSQL_ROOT_PASSWORD=密码
-d mysql
(2)
docker run –p主机端口:容器内部端口 —name 自定义名 –e
MYSQL_ROOT_PASSWORD=密码 -d mysql
几个其它的高级操作:
(1)
docker run —name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
把主机的/my/custom文件夹挂载到mssqldocker容器的/etc/mysql/
conf.d文件夹里面。改mysql的配置文件就只需要把配置文件放在、
(2)
docker run —name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-
pw -d mysql:tag —character-set-server=utf8mb4
—collation-server=utf8mb4_unicode_ci
八、Spring Boot与数据访问
1、原生的JDBC
(1)依赖
(2)在配置文件中编写数据库的四大元素
(3)效果
默认是org.apache.tomcat.jdbc.pool.DataSource作为数据源
数据源的相关配置在DataSourceProperties里面
(4)自动配置原理
1、参考DataSourceConfiguration,根据配置创建数据源,默认
使用org.apache.tomcat.jdbc.pool.DataSource作为数据源
2、可以在配置文件中使用spring.datasource.type来指定自定
义的数据源
3、SpringBoot默认支持的数据源DataSource:
HikariDataSource
org.apache.tomcat.jdbc.pool.DataSource
org.apache.commons.dbcp.BasicDataSource
org.apache.commons.dbcp2.BasicDataSource
任意DataSource
4、自定义数据源类型(源码)
5、DataSourceInitializer
来源:DataSourceAutoConfiguration自动创建Bean对象
实质:是一个ApplicationListener,监听器
作用:
A、runSchemaScripts():运行建表语句
B、runDataScripts():运行插入数据的sql语句
C、默认将文件命名为:schema-.sql、data-.sql
默认路径:classpath:scheam-all.sql
D、也可以使用spring.datasource.schema来指定
文件名字和路径
6、操作数据库
SpringBoot默认自动配置了:JdbcTemplate和
NamedParameterJdbcTemplate
2、使用Druid数据源操作数据库
(1)数据源的其它设置
结果:这些设置默认是绑定不到DataSource内部的,必须进行配置。
原因:因为DataSource.properties内没有这些属性的配置
(2)将上述的其它配置与DataSource.properties进行配置
第一步:编写一个配置类,将DruidDataSource加入容器
第二步:使用@ConfigurationProperties,将配置加入到Properties
中
第三步:测试
(3)配置Druid的监控
第一步:配置一个管理后台的Servlet
初始化配置,详细的配置参数看StaViewServlet类
方法:setInitParameters(Map
第二步:配置一个Web监控的filter
3、整合其他框架
(1)搭建环境
第一步:配置Druid数据源
第二步:建立数据表
第三步:创建Javebean
(2)注解版Mybatis(操作Employee)
第一步:编写一个Mapper接口,在类上使用@Mapper
@Mapper:指定这是一个操作数据库的Mapper
第二步:在Mapper接口编写抽象方法,在方法上使用如下注解:
@Select(“sql语句”):查询
@Delete(“sql语句”):删除
@Insert(“sql语句”):插入
@Option(useGeneratedKeys=true,keyProperty=”
javabean中的属性名”)
@Update(“sql语句”):更新
第三步:编写测试Controller方法
第四步:发现问题
(1)当数据库字段名和javabean的属性名不一致
解决:自定义Mybatis的自动配置规则,给容器中加入
ConfigurationCustomizer
(2)当有很多Mapper接口时,需要在每个接口都@Mapper,麻烦
解决:在SpringBoot的启动类上用@MapperScan(value=”包名”)
(3)配置版Mybatis(操作Department)
第一步:编写全局配置文件(详细看Mybatis文档)
第二步:编写Mapper接口
第三步:编写sql语句的Mapper映射文件(详细看Mybatis文档)
第四步:在配置文件中配置Mybatis的相关配置
目的:告诉SpringBoot,Mybatis的配置类在哪里
第五步:编写测试类Controller方法
(4)介绍Spring Data
概述:是SpringBoot底层默认使用的数据访问技术
子项目:
(5)整合SpringData JPA
第一步:编写实体类和数据库表对应,并配置好映射关系
第二步:编写Repository接口,继承JpaRepository
T: javabean类
ID:主键的类型
接口的功能:有CRUD和分页的功能
ng
第三步:基本配置(详细参照JpaProperties)
第四步:编写测试类的Controller方法
九、Spring Boot启动配置原理
几个重要的时间回调机制:
配置在META-INF/spring.factories中
ApplicationContextInitializer
SpringApplicationRunListener
只需要放在ioc容器中的
ApplicationRunner
CommandLineRunner
1、启动原理
启动流程:
(1)先创建SpringApplication对象
(2)运行run方法
2、事件监听机制
配置在META-INF/spring.factories中
ApplicationContextInitializer
SpringApplicationRunListener
只需要放在ioc容器中的
ApplicationRunner
CommandLineRunner
代码测试:
编写4个类,并依次实现上述的接口,并实现方法。
十、Spring Boot自定义starters
starter:
十一、Spring Boot与缓存
1、JSP107规范
2、Sprng缓存抽象
(1)概述
(2)几个重要的概念和缓存注解
(3)测试使用缓存
步骤:
1、开启基于注解的缓存 @EnableCaching
2、标注缓存注解即可
(1)@Cacheable
作用:将方法的运行结果进行缓存,以后再要相同的数据,直接
从缓存中获取,不用调用方法
属性:
cacheNames/value:指定缓存的名字
(CacheManager管理多个cache组件,对缓存的真正CRUD
操作实在Cache组件中,每一个缓存组件都有自己唯一的
一个名字)
key:缓存数据使用的key,可以用它来指定。默认是方法的
参数值。可以使用SpEL表达式
不能使用#result
KeyGenerator:key的生成器,可以自己指定key的生成器
的组件的id
key/keyGenerator二选一。
自定义KeyGenerator:
第一步:编写一个类,使用@Configuration
第二步:编写一个方法,返回值为KeyGenerator,使用
@Bean(“自定义名”)
第三步:在@Cacheable的属性keyGenerator(“自定义
名”)
CacheManager:指定缓存管理器
CacheResolver:指定缓存解析器
CacheManager/CacheResolver二选一。
condition:指定符合条件的情况下才缓存
unless:否定缓存。当unless指定的条件为true,方法的
返回值就不会被缓存
sync:是否使用异步模式。为true时,不支持unless。
(2)@CacheEvict
作用:缓存清除
属性:同@Cacheable相同
allEntries :是否删除缓存的所有数据。true为是,默
认为false
beforeInvocation :缓存的清除是否在方法之前执行。
默认为false,在方法之后执行,
如果方法内出现异常,缓存就不
会清除。
(3)@CachePut
作用:既调用方法,又缓存数据。可以用来修改数据库的某个数
据,同时更新缓存。
属性:同@Cacheable相同
(4)@Caching
作用:定义复杂的缓存规则
属性:Cacheable[] cacheable
CachePut[] put
CacheEvict[] evict
(5)@CacheConfig
使用:在类上使用
作用:这个类中所有方法的公共缓存规则
属性:@cacheNames
@cacheManager
(4)原理
(5)运行流程
A、@Cacheable:
1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的
名字获取。(CacheManager先获取相应的缓存),第一次获取缓存,如
果没有会自动创建
2、去Cache中查找内容,使用一个key,key默认就是方法的参数
Key是按照某种策略生成的,默认是用keyGenerator生成的,默认
使用SimpleKeyGenerator生成key。
SimpleKeyGenerator生成key的默认策略:
没参数,key=new SimpleKey();
一个参数,key=参数的值;
多个参数,key=new SimpleKey(params);
3、没有查到缓存就调用目标方法
4、将目标方法返回的结果,放进缓存中
B、@CachePut:
1、先调用目标方法
2、将目标方法的结果缓存起来
(6)使用编码的方式操作缓存(与注解的方式不同)
第一步:获取缓存管理器
第二步:通过缓存管理器获取缓存组件
第三步:通过缓存组件的方法,往缓存中存取数据
3、Redis
(1)前述:SpringBoot默认的缓存配置类:SimpleCacheConfiguration,该
配置类注册了:ConcurrentMapCacheManager缓存管理器和
ConcurrentMapCache缓存组件。
(2)概述:实际的开发中,经常使用缓存中间件:Redis,Memcached,Ehcache
(3)安装
1、下载和安装redis
Windows: 下载和安装RedisDestopManager客户端
Linux: 使用镜像加速下载Redis,命令:docker pull
registry.docker-cn.com/library/redis
2、启动redis服务器
Windows:进入安装目录,在控制台输入命令:
linux:docker run –d –p 6349:6349 –name myredis 编号
(4)数据类型:
String(字符串)
List(列表)
Set(无序集合)
Hash(散列)
ZSet(有序集合)
(5)整合的步骤:
第一步:引入redis的starter
知识点:引入了redis之后,RedisAutoConfiguration自动配置类
就会起作用,且注册了两个操作Redis的类:RedisTemplate,
StringRedisTemplate。
RedisTemplate:key-value都是Object类型
StringTemplate:专门用于操作key-value都是字符串
第二步:配置redis,连接redis服务端
spring.redis.host=localhost
第三步:测试使用
(6)StringRedisTemplate,RedisTemplate
方法:opsForList.命令() 操作List(列表)
opsForSet.命令() 操作Set(集合)
opsForHash.命令() 操作Set(集合)
opsForValue.命令() 操作String(字符串)
opsForZSet.命令() 操作ZSet(有序集合)
问题1:直接使用RedisTemplate保存对象时,会报错
解决1:对象类需要实现序列化接口,保存的结果是序列化后的数据
问题2:序列化的数据看不懂,如何用json的方式保存
解决2:
(1)将对象转为json格式
(2)RedisTemplate默认的序列化规则就是Jdk的序列化规则
可以编写配置类,来修改默认的序列化规则,修改为
Jackson2JsonRedisSerializer
(7)测试缓存
原理:CacheManager创建Cache,缓存组件来给缓存存取数据
(1)引入redis的starter,容器中保存的是RedisCacheManager
(2)RedisManager帮我们创建RedisCache作为缓存组件,
RedisCache通过redis来操作缓存数据的
(3)默认保存数据,key-value都是Object,利用序列化保存
问题:如何将缓存以json格式保存
原理:
1、引入了redis的starter,cacheManager变为
RedisCacheManager
2、操作缓存时使用的是RedisTemplate
@EnableScheduling:开启基于注解的定时任务
3、邮件任务
步骤:
第一步:导入邮件的starter
第二步:编写配置文件:
spring.mail.username=发件人邮箱地址
spring.mail.password=授权码
spring.mail.host=smtp.126/qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
第三步:创建邮件对象
简单邮件对象(不带附件):SimpleMailMessage
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
所在包:org.springframework.mail
邮件的设置:(使用SimpleMailMessage来调用下面的方法)
设置主题:SetSubject(“”)
设置正文:setText(“”,是否转成html:true/false[默认]);
设置发件人:setFrom(“”)
设置收件人:setTo(“”)
带附件的邮件对象:MimeMessage
所在包:javax.mail.internet
邮件的设置:(同上,使用MimeMessageHelper来调用下列方法)
发送附件:addAttachment(“”,File file);
注意:要想发送附件成功,创建MimeMessageHelper时,
multipart必须设置为true
第四步:发送邮件
自动注入JavaMailSenderImpl对象。
使用JavaMailSenderImpl对象来发送邮件。
方法:
send(SimpleMailMessage/MimeMessage);
十五、Spring Boot与安全
1、登陆&认证&授权
第一步:引入SpringSecurity
第二步:编写SpringSecurity的配置类
使用@EnableWebSecurity,继承WebSecurityConfigurerAdapter
第三步:控制请求的访问权限
A、重写configure(HttpSecurity http)方法:
(1)定制请求的授权规则
方法:
1.authorizeRequests()
2.antMatchers(“路径”)
3.permitAll() 允许所有访问
4.hasRole(“”)
使用:
http.authorizeRequests().antMatchers(“/“).permitAll()
.antMatchers(“/level1/*“).hasRole(“VIP1”)
(2)开启自动配置的登陆功能
方法:
formLogin()
使用:http.formLogin()
规则:
1./login来到登陆页面
2.重定向到/login?error表示登陆失败
3.更多详细规定
B、重写configure(AuthenticationManagerBuilder auth)方法:
作用:定义认证规则
注意:SpringSecurity 5.0增加了加密方式,也改变了密码的格式。
Spring Security中密码的存储格式是“{id}…………”。前
面的id是加密方式,id可以是bcrypt、sha256等,后面跟
着的是加密后的密码。也就是说,程序拿到传过来的密码的
时候,会首先查找被“{”和“}”包括起来的id,来确定后
面的密码是被怎么样加密的,如果找不到就认为id是null。
解决:修改一下configure中的代码。我们要将前端传过来的密码
进行某种方式加密,spring security 官方推荐的是使用
bcrypt加密方式
方法:
auth.inMemoryAuthentication().passwordEncoder(new
BCryptPasswordEncoder()).
withUser(“用户名”).password(new
BCryptPasswordEncoder().encode(“123456”)).roles(“角
色1”,”角色2”)
.and()
. 同上
2、权限控制&注销
A、注销
位置:在configure(HttpSecurity http)方法中使用
方法:logout()
使用:http.logout()
规则:
1、访问/logout表示用户注销,并清空session。注销后返回登陆页
面,路径/logout?logout
定制:
1、logoutSuccessUrl(“”) 注销成功后返回的地址
B、SpringSecurity在页面中的使用
第一步:
必须手动导入依赖:thymeleaf-extras-springsecurity5
第二步:在页面中导入xmlns:sec
http://www.thymeleaf.org/thymeleaf-extras-springsecurity4”
第三步:了解sec标签
官方文档的原意:
1、sec:authorize
sec:authorize attribute renders its content when
the attribute expression is evaluated to true
2、sec:authentication
sec:authentication attribute is used to print
logged user name and roles
sec:authentication=”name” 输出用户名
sec:authentication=”principal.authorities”
作用:输出角色名
3、记住我
A、记住我
位置:在configure(HttpSecurity http)方法中使用
方法:rememberMe()
使用:http.rememberMe()
原理:将cookie发给浏览器保存,以后访问页面带上这个cookie,只要
通过检查就可以免登陆。点击注销会删除cookie。
B、定制登录页
错误想法:不能直接写一个/login的Controller方法,无法去到方法
所指定的登陆页面
正确做法:在formLogin()方法后添加loginPage(“”)方法,填入去到
指定的登陆页面的请求地址。
1、默认get形式的/login代表来到登陆页面
默认post形式的/login代表处理登陆请求
2、一旦设置loginPage后,那么post形式的自定义地址就是处理登陆
请求,get形式的自定义地址就是来到登陆页面,可以通过
loginProcessingUrl方法来修改post形式的地址。
C、在定制的登陆页面中加入“记住我”功能
表单控件的name属性和rememberMeParameter(“”)一致即可。
十六、Spring Boot与分布式
1、Zookeeper和Dubbo
2、Dubbo工作流程图
Zookeeper是一个注册中心,A服务先在注册中心中寻找B服务地址,知
道地址后,再去寻找B服务,是一个服务软件。
Dubbo是分布式服务的调用框架。
2、Docker安装Zookeeper
docker pull registry.docker-cn.com/library/zookeeper:3.4
注意:不声明版本,默认使用latest版本,会报错。
启动Zookeeper:
4、SpringBoot,Dubbo,Zookeeper整合
第一步:创建工程
1、先创建Empty Project
2、创建两个Module(Springboot工程)
第二步:将服务提供者注册到注册中心
1、在提供者中导入dubbo的starter和zookeeper工具包
版本必须是0.2以上。
2、配置Dubbo的相关属性
dubbo.application.name=当前应用的名字
dubbo.registry.address=注册中心的地址
dubbo.scan.base-packages=发布出去的包
3、开启Dubbo
使用@EnableDubbo注解开启Dubbo
4、将服务发布出去
在发布出去的包的实现类中加入注解@Service(Dubbo包的注解)
将类加入到容器中@Component
第三步:在服务消费者中引用服务提供者
1、引入依赖(同上)
2、配置dubbo的注册中心地址
3、开启Dubbo(同上)
3、引用服务
1、将接口的包和类本身复制到消费者项目中
2、声明接口变量,并使用@Reference注解,将类注入到容
器中
@Reference:Dubbo包
@Service:Spring包
3、在测试类中测试
5、SpringBoot与SpringCloud的整合
第一步:创建空工程和三个子工程
eureka-server:注册中心
provider-ticket:服务提供者
consumer-user:服务消费者
第二步:配置注册中心
1、配置Eureka信息
eureka:
instance:
hostname: # eureka实例的主机名
client:
register-with-eureka:false #不把自己注册到eureka上 fetch-registry:false #不从eureka上获取服务的注册信息
2、@EnableEurekaServer开启Eureka
第三步:编写服务提供者,将服务注册到注册中心去
1、编写服务方法
2、编写配置信息
eureka:
instance:
prefer-ip-address: true #注册服务的时候使用ip地址注册
spring:
application:
name: #应用名
第四步:编写服务消费者,远程消费服务
1、编写消费方法
restTemplate():
第一个参数:访问服务提供者的地址,用http://服务名/请
求地址来访问即可
第二个参数:响应结果返回的类型
2、往容器添加RestTemplate组件
3、编写配置信息
十六、Spring Boot与热部署
1、热部署
在开发中修改了一个java文件后想看到最新的效果,就必须得重启应用。 这导致大量时间被浪费了。在不重启应用程序的情况下,程序可以自动部
热署。
2、实现热部署的方法(4种)
1、模版引擎
在Springboot中禁用掉模版引擎的cache,然后在页面模版中使用
Ctrl+F9可以重新编译当前页面并生效。
2、Spring Loaded
Spring官方提供的热部署程序,实现修改类文件的热部署
-下载Spring Loaded
-添加运行时参数:
-javaagent:C:/springloaded-1.2.5.RELEASE.jar -noverify
3、JRebel
-收费的一个热部署软件
-安装插件即可使用
4、Spring Boot Devtools(推荐)
-引入依赖
十七、Spring Boot与监控
1、监控管理
通过引入spring-boot-starter-actuator,可以使用SpringBoot为我们提
供的准生产环境下的应用监控和管理功能。我们可以通过HTTP,JMX,SSH协议来进行操作,自动得到审计、健康以指标信息等。
2、步骤
1、引入spring-boot-starter-actuator
2、通过http方式访问监控端点
3、可进行shutdown(POST提交,此端点默认关闭)
3、 端点名
因为以上地址都是被保护起来的,要想查看必须关闭保护,必须设置
management.security.enabled=false。
(1)/info:访问的时当前应用信息
添加应用信息:info.xx= info.xx=
(2)endpoints.shutdown.enabled=true,可以发送post请求,远程关
闭当前应用。
4、定制端点信息
方法:Endpoints+端点名+属性名=
(1)关闭所有的端点访问
Endpoints.enabled=false
(2)定制端点访问的根路径
management.context-path=/xxx
(3)关闭http端点
management.port=-1
关闭后,无论哪个端口号都访问不到端点
5、自定义HealthIndicator(健康状态检查指示器)
第一步:编写一个指示器,实现HealthIndicator接口
健康:Health.up().build()
不健康:Health.up().withDetail(“msg”,”异常信息”).build()
第二步:指示器的名字:xxxHealthIndicator
第三步:加入到容器中