SpringBoot 总笔记

注意springboot_01_hello不是使用springInitializr创建的

一、SpringBoot入门

1、基本介绍

优点:

2、微服务

3、MAVEN设置

mavensettings.xml配置文件的profiles标签添加下面的代码:

表示maven使用jdk1.8

4、Spring Boot HelloWorld

实现功能:

浏览器发送hello请求,服务器接受请求并处理,响应Hello Springboot!字符串;即浏览器输入 localhost:8080/hello可以看到浏览器显示Hello SpringBoot!字符串;

① 创建一个maven工程(jar);

② 导入spring boot相关的依赖;

③ 编写一个主程序,启动Spring Boot应用

④ 编写相关的Controller

⑤ 运行主程序测试

⑥简化部署

将这个应用打成jar包,直接使用java-jar的命令进行执行;

结果:

 

 

5、Hello World探究

(1)、Pom.xml文件

父项目

他的父项目:

他来真正管理Spring Boot应用里面的所有依赖版本;

也就是Spring Boot的版本仲裁中心;

以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)

启动器:

spring-boot-starter-web:

Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器。

(2)、主程序类,主入口类

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot主配置类SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;这是一个组合注解

下面看里面的每个注解含义:

配置类 -----> 配置文件;配置类也是容器中的一个组件:@Component

@EnableAutoConfiguration:开启自动配置功能;

以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

6、使用Spring Initializer快速创建Spring Boot项目

IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目。选择我们需要的模块,向导会联网创建Spring Boot项目,默认生成的Spring Boot项目; 主程序生成好了,我们只需要我们自己的逻辑。

 

 

 

 

结构目录:

简单Controller,注意@RestController注解。

 


二、配置文件

1、配置文件

SpringBoot使用一个全局的配置文件,下面两者都会当做是配置文件,配置文件名是固定的;

配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好;

YAML(YAML Ain't Markup Language)

标记语言: 以前的配置文件,大多都使用的是xxxx.xml文件;

YAML:以数据为中心,比jsonxml等更适合做配置文件

yaml配置例子:

对应xml配置例子:

2、YAML语法

基本语法:

值的写法:

字符串默认不用加上单引号或者双引号

对象、Map(属性和值)(键值对):

k: v:在下一行来写对象的属性和值的关系,注意缩进。 对象还是k: v的方式

 

行内写法:

数组(ListSet): - 值(注意有空格)表示数组中的一个元素

行内写法

3、配置文件值注入-对应springboot_02_config项目

JavaBean配置:

application.yml文件配置

可以导入配置文件处理器,以后编写配置就有提示了。

4、application.yml对应的application.properties配置-springboot_02_config_2_propertiesonfig项目

上面的application.yml配置文件也可以使用application.properties文件来替换:

5、@Value获取值和@ConfigurationProperties获取值比较

 @ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法-支持不支持
SpEL(Spring表达式)不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

配置文件yml还是properties他们都能获取到值;

如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value

如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties

6、@PropertySource&@ImportResource&@Bean

对应项目: springboot_02_config_3_propertysource_importresource

@PropertySource:加载指定的配置文件。

@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;

Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;

想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上。

导入Spring的配置文件让其生效。

SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式

1、配置类@Configuration------> Spring配置文件;

2、使用@Bean给容器中添加组件;

测试类:

7、配置文件占位符

没有专门写一个项目。

1、这些表达式可以出现在配置文件中:

例如application.properties

2、占位符获取之前配置的值,如果没有可以是用:指定默认值

比如:

8、Profile切换环境

springboot_02_config_4_profile项目。

(1)、多Profile文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml

默认使用application.properties的配置;

(2)、yml支持多文档块方式

这种方式也是和properties配置文件的指定方式差不多。

(3)、激活指定profile

1、在配置文件中指定 spring.profiles.active=dev

例如项目中有三个properties文件,分别是application.properties、application-dev.properties、application-prod.properties

内容如下:

application.properties:

application-dev.properties:

application-prod.properties:

因为在application.properties中配置了使用prod环境,所以最终项目在8082端口启动了。

2、IDEA中配置命令行参数--spring.profiles.active=dev

最终下面显示还是在dev这个环境中启动,所以说命令行参数的优先级>配置文件的优先级

3、命令行:java -jar springboot_02_config_4_profile-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev

可以直接在测试的时候,配置传入命令行参数

4、虚拟机参数: -Dspring.profiles.active=dev

9、配置文件位置

项目: springboot_02_config_5_locationofproperties

SpringBoot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

SpringBoot会从这四个位置全部加载主配置文件;互补配置

例如:

这里使用–classpath:/config/–classpath:/下的两个application.properties来测试一下:

 

相关代码:

classpath:/config/application.properties

classpath:/application.properties:

TestController:

 

我们还可以通过spring.config.location来改变默认的配置文件位置;

项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;

java -jar springboot_02_config_5_locationofproperties-0.0.1-SNAPSHOT.jar --spring.config.location=/home/zxzxin/IDEA/application.properties

 

10、外部配置加载顺序

SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置,下面的11个配置重点是5个加粗样式的。

1.命令行参数

所有的配置都可以在命令行上进行指定

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

多个配置用空格分开; --配置项=值

2.来自java:comp/env的JNDI属性

3.Java系统属性(System.getProperties())

4.操作系统环境变量

5.RandomValuePropertySource配置的random.*属性值

由jar包外向jar包内进行寻找;

优先加载带profile

6.jar包外部的application-{profile}.propertiesapplication.yml(带spring.profile)配置文件

7.jar包内部的application-{profile}.propertiesapplication.yml(带spring.profile)配置文件

再来加载不带profile

8.jar包外部的application.propertiesapplication.yml(不带spring.profile)配置文件

9.jar包内部的application.propertiesapplication.yml(不带spring.profile)配置文件

10.@Configuration注解类上的@PropertySource

11.通过SpringApplication.setDefaultProperties指定的默认属性

所有支持的配置加载来源;

详细参考官方文档

 

11、自动配置原理-重点

配置文件到底能写什么?怎么写?自动配置原理;

配置文件能配置的属性参照

(1)、自动配置原理:

1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration

2)、@EnableAutoConfiguration 作用:

每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

3)、每一个自动配置类进行自动配置功能;

4)、以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;

根据当前不同的条件判断,决定这个配置类是否生效。

一旦这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

 

5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者;配置文件能配置什么就可以参照某个功能对应的这个属性类

 

 

SpringBoot精髓:

1)、SpringBoot启动会加载大量的自动配置类

2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;

3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)

4)、给容器中自动配置类添加组件的时候,会从xxxProperties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

 

xxxxAutoConfigurartion:自动配置类 ---> 给容器中添加组件;

xxxxProperties : 封装配置文件中相关属性;

 

(2)、细节-@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

@Conditional扩展注解作用(判断是否满足当前指定条件)
@ConditionalOnJava系统的java版本是否符合要求
@ConditionalOnBean容器中存在指定Bean;
@ConditionalOnMissingBean容器中不存在指定Bean;
@ConditionalOnExpression满足SpEL表达式指定
@ConditionalOnClass系统中有指定的类
@ConditionalOnMissingClass系统中没有指定的类
@ConditionalOnSingleCandidate容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty系统中指定的属性是否有指定的值
@ConditionalOnResource类路径下是否存在指定资源文件
@ConditionalOnWebApplication当前是web环境
@ConditionalOnNotWebApplication当前不是web环境
@ConditionalOnJndiJNDI存在指定项

自动配置类必须在一定的条件下才能生效;

我们怎么知道哪些自动配置类生效;

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;


三、日志

1、日志框架

一个小故事:

小张;开发一个大型系统;

1、System.out.println("");将关键数据打印在控制台;去掉?写在一个文件?

2、框架来记录系统的一些运行时信息;日志框架 ; zhanglogging.jar;

3、高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar?

4、将以前框架卸下来?换上新的框架,重新修改之前相关的API;zhanglogging-prefect.jar;

5、JDBC---数据库驱动;

写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;

给项目中导入具体的日志实现就行了;我们之前的日志框架都是实现的抽象层;

 

市面上的日志框架 :

JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....

日志门面 (日志的抽象层)日志实现
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-loggingLog4j JUL(java.util.logging) Log4j2 Logback

左边选一个门面(抽象层)、右边来选一个实现;

我们最终选用的是:

SpringBoot:底层是Spring框架,Spring框架默认是用JCL;SpringBoot选用 SLF4j和logback;

2、SLF4j使用

如何在系统中使用SLF4j https://www.slf4j.org

以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;

给系统里面导入slf4jjarlogback的实现jar

图示;

每一个日志的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件;

3、SpringBoot和其他框架整合时日志的统一管理问题-legacyProblem

SpringBoot(slf4j+logback)、Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、xxxx

统一日志记录,即使是别的框架和我一起统一使用slf4j进行输出?

如何让系统中所有的日志都统一到slf4j

1、将系统中其他日志框架先排除出去;

2、用中间包来替换原有的日志框架;

3、我们导入slf4j其他的实现

4、SpringBoot日志关系

首先依赖于spring-boot-starter

其中spring-boot-starter又包含spring-boot-starter-logging,使用它来做日志功能;

底层依赖关系:

总结:

1)、SpringBoot底层也是使用slf4j+logback的方式进行日志记录;

2)、SpringBoot也把其他的日志都替换成了slf4j

3)、中间替换包:jcl-over-slf4j.jar、log4j-over-slf4j.jar、jul-to-slf4j.jawr等;

 

4)、如果我们要引入其他框架,一定要把这个框架的默认日志依赖移除掉;

Spring框架用的是commons-logging;(这里如果是前面1.5版本的会有下面的代码,但是2.0+版本的没有)

SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;

5、日志使用

springboot_03_logging项目。

SpringBoot默认帮我们配置好了日志;

SpringBoot修改日志的默认配置

logging.filelogging.pathExampleDescription
(none)(none) 只在控制台输出
指定文件名(none)my.log输出日志到my.log文件
(none)指定目录/var/log输出到指定目录的 spring.log 文件中

默认配置文件位置:

指定配置

给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了

Logging SystemCustomization
Logbacklogback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
Log4j2log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging)logging.properties

logback.xml:直接就被日志框架识别了;

logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能

logback-spring.xml配置文件如下:

运行项目:

如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误:

6、日志框架切换

可以按照slf4j的日志适配图,进行相关的切换;

slf4j+log4j的方式;

sjf4j中使用log4j(而不是logback):

切换为log4j2(可能用到)

springboot_03_logging_2_uselog4j2项目。

pom.xml改动:

效果:


四、Web开发

1、简介

使用SpringBoot:

1)、创建SpringBoot应用,选中我们需要的模块;

2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来;

3)、自己编写业务代码即可;

 

自动配置原理?

这个场景SpringBoot帮我们配置了什么?能不能修改?能修改哪些配置?能不能扩展?xxx

 

2、SpringBoot对静态资源的映射规则

SpringMVC的自动配置都在WebMVCAutoConfiguration类中。下面是对静态资源的一些配置:

具体代码如下:

对这对代码的总结:

1)、所有/webjars/** ,都去classpath:/META-INF/resources/webjars/找资源;

webjars:以jar包的方式引入静态资源;http://www.webjars.org/

导入之后,查看maven依赖的目录结果,就是上面的classpath:/META-INF/resources/webjars/目录:

启动项目之后,可以直接在浏览器访问到jquery: 输入http://localhost:8080/webjars/jquery/3.3.1-1/jquery.js

 

2)、"/**" 访问当前项目的任何资源(自己添加的静态资源),都去(静态资源的文件夹)找映射

比如在上面的代码中还有一个行Duration cachePeriod = this.resourceProperties.getCache().getPeriod();

这个resourceProperties是类ResourceProperties的对象,可以设置和静态资源有关的参数,比如缓存时间等。相关代码如下:

下面就是几个静态资源的文件夹

例如,访问项目的下静态资源http://localhost:8080/asserts/js/Chart.min.js去静态资源文件夹里面找Chart.min.js:

 

 

也可以在application.properties中定义自己的静态资源文件夹:

3)、欢迎页; 静态资源文件夹下的所有index.html页面,被"/**"映射;

localhost:8080/index.html页面

4)、所有的 **/favicon.ico 都是在静态资源文件下找;

下面是WebMVCAutoConfiguration里面的内部类FaviconConfiguration:

测试: 将favicon.ico放在META-INF/resources下(也是静态资源文件夹):

 

3、模板引擎thymeleaf

模板引擎的作用: 将页面模板和组装的数据交给模板引擎,模板引擎将页面中的表达式解析,填充到指定的位置,生成我们想要的内容。

SpringBoot推荐Thymeleaf,语法更简单,功能更强大。

(1)、引入thymeleaf

但是像上面那样配置之后项目启动会出错:

原因就是不能自己覆盖那个版本,但是教程上覆盖貌似是可以。。

解决错误博客

所以pom.xml还是不能将thymeleaf的版本更改,直接用springboot默认的版本即可。

测试结果: (classpath:/tmplates/success.html)

(2)、Thymeleaf使用

默认规则:

只要我们把HTML页面放在classpath:/templates/thymeleaf就能自动渲染;

使用:

1、导入thymeleaf的名称空间

一个关于IDE的问题: Thymeleaf在IDEA中的红色波浪线问题

2、使用thymeleaf语法;

(3)、语法规则

在线教程

1)、th:text;改变当前元素里面的文本内容;

th:任意html属性;来替换原生属性的值

 

2)、表达式语法

具体参见: 在线文档

1)、获取对象的属性、调用方法; 2)、使用内置的基本对象; 3)、内置的一些工具对象;

Simple expressions:

Literals(字面值)

Text operations:(文本操作)

Arithmetic operations:(算数运算)

Boolean operations:(布尔运算)

Comparisons and equality:(比较运算)

Conditional operators:(条件运算)

Special tokens:

简单使用测试:

相关代码:

Controller:

success.html:

4、SpringMVC自动配置

(1)、SpringMVC Auto Configuration

在线文档参考org.springframework.boot.autoconfigure.web:web的所有自动场景。

Spring MVC auto-configuration,即SpringBoot自动配置好了SpringMVC,

自己添加的格式化器转换器,我们只需要放在容器中即可。

If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

(2)、扩展SpringMVC

以前的配置,视图解析viewController,以及拦截器(interceptor)。

编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc;

既保留了所有的自动配置,也能用我们扩展的配置,下面是SpringBoot1.0以上的,但是现在过时了

相关博客解释1

相关博客解释2

SpringBoot2.0以上的替代方案:

原理:

1)、WebMvcAutoConfiguration是SpringMVC的自动配置类;

2)、在做其他自动配置时会导入;@Import(EnableWebMvcConfiguration.class)

3)、容器中所有的WebMvcConfigurer都会一起起作用;

4)、我们的配置类也会被调用;

效果:SpringMVC的自动配置和我们的扩展配置都会起作用;

(3)、全面接管SpringMVC

这个就是当你标注了@EnableWebMvc注解,就可以完全的控制SpringMVC了(SpringBoot对SpringMVC不会起作用了)。

SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置;所有的SpringMVC(web场景)的自动配置都失效了。

我们需要在配置类中添加@EnableWebMvc即可;

原理:

为什么@EnableWebMvc自动配置就失效了;

1)、@EnableWebMvc的核心

2)、导入的DelegatingWebMvcConfiguration类:

3)、而WebMvcAutoConfiguration类的开始是这样写的: 关键就在这一行@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

4)、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;

5)、而导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;

5、如何修改SpringBoot的默认配置

模式:

1)、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;

2)、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置;

3)、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置;

 

6、Restful-CRUD

(1)、默认访问首页

如果我们在静态资源文件夹(public、META-INF/resources、resources、static)中放了index.html页面,就不会默认访问到我们在template下面的首页,有两种方法可以解决这个问题。

方法一:

方法二:

另外,可以用Thymeleaf来替换login.html中的一些代码。这样,当改变项目名称时不会受影响。

(2)、国际化

以前SpringMVC的配置步骤:

1)、编写国际化配置文件;

2)、使用ResourceBundleMessageSource管理国际化资源文件;

3)、在页面使用fmt:message取出国际化内容;

 

现在SpringBoot帮我们做好了后面的两项。我们只需要编写配置文件即可。

步骤:

1)、编写国际化配置文件,抽取页面需要显示的国际化消息;

2)、SpringBoot自动配置好了管理国际化资源文件的组件MessageSourceAutoConfiguration

3)、编写配置基础名的配置文件代码;

4)、去页面获取国际化的值;

login.html完整代码:

效果:根据浏览器语言设置的信息切换了国际化;

原理:

国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象);

4)、可以配置自己的LocaleResolver点击链接切换国际化

login.html更改:

 

最后记得要注册这个组件。

(3)、登陆

开发期间模板引擎页面修改以后,要实时生效:

1)、禁用模板引擎的缓存;

2)、页面修改完成以后ctrl+f9:重新编译;

 

实现登录的前端代码,在form表单添加action

具体代码:

登陆错误消息的显示

 

后台Java代码:

 

防止表单的重复提交

(4)、拦截器进行登录检查

如果按照上面的处理(对重复提交表单的处理)会发生你登录之后在另一个浏览器中不需要登录可以直接访问dashboard.html(main.html)的情况,所以要使用拦截器interceptor进行拦截器检查。

自已定义一个LoginHandlerInterceptor

在MVC的配置类MyMvcConfig注册拦截器:

效果:

(5)、CRUD员工列表

实验要求:

1)、RestfulCRUD:CRUD满足Rest风格;

URI: /资源名称/资源标识 : HTTP请求方式区分对资源CRUD操作

 普通CRUD(uri来区分操作)RestfulCRUD
查询getEmpemp---GET
添加addEmp?xxxemp---POST
修改updateEmp?id=xxx&ooo=xxemp/{id}---PUT
删除deleteEmp?id=1emp/{id}---DELETE

2)、实验的请求架构;

实验功能请求URI请求方式
查询所有员工empsGET
查询某个员工(来到修改页面)emp/1(emp/{id})GET
来到添加页面empGET
添加员工empPOST
来到修改页面(查出员工进行信息回显)emp/1GET
修改员工empPUT
删除员工emp/1DELETE

3)、员工列表:

thymeleaf公共页面元素抽取(因为员工列表页面list.html的顶部和左边都是和dashboard.html相同,所以可以将公共部分抽取出来)

三种引入公共片段的th属性:

th:insert:将公共片段整个插入到声明引入的元素中

th:replace:将声明引入的元素替换为公共片段

th:include:将被引入的片段的内容包含进这个标签中

dashboard.html顶部公共元素抽取:

list.html中引入:

dashboard.html侧栏公共元素抽取:

list.html中引入:

先删除原来的nav标签(侧栏):

引入新的:

 

引入片段的时候传入参数: (这个解决的就是侧栏的点击高亮问题(当前选项高亮))

此时将公共部分抽取出来bar.html(不是将公共部分继续放在dashboard.html中):

(1).bar.html中添加th:class属性判断(带参数)

(2). list.htmldashboard.html引入更改:

list.html页面员工展示:

效果:

(6)、CRUD员工添加

list页面添加按钮:

 

controlloer:

add.html页面中的表单添加页面

提交的数据格式不对:生日:日期;

2017-12-12;2017/12/12;2017.12.12;

配置(application.properties中配置)

日期的格式化;SpringMVC将页面提交的值需要转换为指定的类型;

2017-12-12---Date; 类型转换,格式化;

默认日期是按照/的方式;

(7)、CRUD员工修改

修改添加二合一表单

后台java代码:

来到修改页面代码:

真正修改:

 

(8)、CRUD员工删除

后台java代码:

 

7、错误处理机制

(1)、SpringBoot默认的错误处理机制

默认效果,浏览器返回一个默认的错误页面

浏览器发送请求的请求头():

如果是其他客户端,默认响应一个json数据(Postman客户端查看):

原理:

可以参照ErrorMvcAutoConfiguration;错误处理的自动配置;

给容器中添加了以下组件:

1、DefaultErrorAttributes

2、BasicErrorController:处理默认/error请求(可以在配置文件中配置)

这个就是上面那两种的html错误页面和json的效果。

比如默认网页错误页面发送的请求头:

客户端的:

3、ErrorPageCustomizer

4、DefaultErrorViewResolver

步骤:

一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error请求;就会被BasicErrorController处理;

1)响应页面: 去哪个页面是由DefaultErrorViewResolver解析得到的;

2)响应json数据的处理:

(2)、如何定制错误响应

a、如何定制错误的页面;

1)、有模板引擎的情况下;error/状态码;【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的 error文件夹下】,发生此状态码的错误就会来到对应的页面;

我们可以使用4xx5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态码.html)

页面能获取的信息;

timestamp:时间戳

status:状态码

error:错误提示

exception:异常对象

message:异常消息

errors:JSR303数据校验的错误都在这里

2)、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;

3)、以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

b、如何定制错误的json数据;

开始测试:

客户端方式:

1)、自定义异常处理 & 返回定制json数据:

效果:

代码:

2)、转发到/error进行自适应响应效果处理

效果:

来源: BasicErrorController中errorHtml方法中的getStatus方法里面:

具体的设置代码(有自适应效果):

3)、将我们的定制数据携带出去;

出现错误以后,会来到/error请求,会被BasicErrorController处理,响应出去可以获取的数据是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);

1、完全来编写一个ErrorController(就不会用默认的)的实现类【或者是编写AbstractErrorController的子类】,放在容器中;(比较复杂 )

2、页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到; 容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;

自定义ErrorAttributes

最终的效果:响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容。

8、配置嵌入式Servlet容器

SpringBoot默认使用Tomcat作为嵌入式的Servlet容器;

问题?

1)、如何定制和修改Servlet容器的相关配置

1、方法一: 修改和server有关的配置(ServerProperties【也是EmbeddedServletContainerCustomizer】);

2、方法二: 编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器;来修改Servlet容器的配置

这是SpringBoot1.0的废弃方案:

SpringBoot2.0的新方案:

2)注册Servlet三大组件【Servlet、Filter、Listener】

由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。(以前是在webapp/WEB-INF/web.xml下注册)

注册三大组件用以下方式

ServletRegistrationBean

FilterRegistrationBean

ServletListenerRegistrationBean

SpringBoot帮我们自动SpringMVC的时候,自动的注册SpringMVC的前端控制器;DispatcherServlet

DispatcherServletAutoConfiguration中:

3)、替换为其他嵌入式Servlet容器(SpringBoot能不能支持其他的Servlet容器)

默认支持:

Tomcat(默认使用)

Jetty

Undertow

4)、嵌入式Servlet容器自动配置原理;

EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置?

1)、EmbeddedServletContainerFactory(嵌入式Servlet容器工厂)

2)、EmbeddedServletContainer:(嵌入式的Servlet容器)

3)、以TomcatEmbeddedServletContainerFactory为例

4)、我们对嵌入式容器的配置修改是怎么生效?

EmbeddedServletContainerCustomizer:定制器帮我们修改了Servlet容器的配置?

怎么修改的原理?

5)、容器中导入了EmbeddedServletContainerCustomizerBeanPostProcessor

原理步骤:

1)、SpringBoot根据导入的依赖情况,给容器中添加相应的EmbeddedServletContainerFactory【如TomcatEmbeddedServletContainerFactory

2)、容器中某个组件要创建对象就会惊动后置处理器;EmbeddedServletContainerCustomizerBeanPostProcessor

只要是嵌入式的Servlet容器工厂,后置处理器就工作;

3)、后置处理器,从容器中获取所有的EmbeddedServletContainerCustomizer调用定制器的定制方法

 

5)、嵌入式Servlet容器启动原理;

什么时候创建嵌入式的Servlet容器工厂?什么时候获取嵌入式的Servlet容器并启动Tomcat;

获取嵌入式的Servlet容器工厂:

1)、SpringBoot应用启动运行run方法;

2)、refreshContext(context);SpringBoot刷新IOC容器【创建IOC容器对象,并初始化容器,创建容器中的每一个组件】;如果是web应用创建AnnotationConfigEmbeddedWebApplicationContext,否则:AnnotationConfigApplicationContext

3)、refresh(context);刷新刚才创建好的ioc容器;代码如下:

4)、onRefresh();web的IOC容器重写了onRefresh方法

5)、webIOC容器会创建嵌入式的Servlet容器;createEmbeddedServletContainer();

6)、获取嵌入式的Servlet容器工厂:

TomcatEmbeddedServletContainerFactory创建对象,后置处理器BeanPostProcesser一看是这个对象,就获取所有的定制器来先定制Servlet容器的相关配置;

7)、使用容器工厂获取嵌入式的Servlet容器

8)、嵌入式的Servlet容器创建对象并启动Servlet容器;

先启动嵌入式的Servlet容器,再将ioc容器中剩下没有创建出的对象获取出来;

IOC容器启动创建嵌入式的Servlet容器

9、使用外置的Servlet容器

嵌入式Servlet容器:应用打成可执行的jar

可以使用外置的Servlet容器:外面安装Tomcat---应用war包的方式打包;

(1)、步骤

1)、必须创建一个war项目;(利用idea创建好目录结构)

可以将应用打成war包,也可以将IDE整合外部服务器tomcat:

2)、将嵌入式的Tomcat指定为provided

3)、必须编写一个SpringBootServletInitializer的子类,并调用configure方法

4)、启动服务器就可以使用;

(2)、原理

两种方式的不同原理:

servlet3.0(Spring注解版):章节: 8.2.4 Shared libraries / runtimes pluggability;

规则:

1)、服务器启动(web应用启动)会创建当前web应用里面每一个jar包里面ServletContainerInitializer实例:

2)、ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下,有一个名为javax.servlet.ServletContainerInitializer的文件,内容就是ServletContainerInitializer的实现类的全类名

3)、还可以使用@HandlesTypes,在应用启动的时候加载我们感兴趣的类;

 

流程:

1)、启动Tomcat;

2)、org\springframework\spring-web\4.3.14.RELEASE\spring-web-4.3.14.RELEASE.jar!\META-INF\services\javax.servlet.ServletContainerInitializer

Spring的web模块里面有这个文件:org.springframework.web.SpringServletContainerInitializer

3)、SpringServletContainerInitializer@HandlesTypes(WebApplicationInitializer.class)标注的所有这个类型的类都传入到onStartup方法的Set<Class<?>>;为这些WebApplicationInitializer类型的类创建实例;

4)、每一个WebApplicationInitializer都调用自己的onStartup;

5)、相当于我们的SpringBootServletInitializer的类会被创建对象,并执行onStartup方法;

6)、SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext;创建容器

下面是SpringBootServletInitializercreateRootApplicationContext方法:

7)、Spring的应用就启动并且创建IOC容器(run方法)

即先启动Servlet容器,再启动SpringBoot应用


五、Docker

1、简介

Docker是一个开源的应用容器引擎;是一个轻量级容器技术;

Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像;

运行中的这个镜像称为容器,容器启动是非常快速的。

Docker的思想和虚拟机类似,但是实际还是有区别的。

 

2、核心概念

使用Docker的步骤:

1)、安装Docker

2)、去Docker仓库找到这个软件对应的镜像;

3)、使用Docker运行这个镜像,这个镜像就会生成一个Docker容器;

4)、对容器的启动停止就是对软件的启动停止;

3、安装Docker

1)、安装linux虚拟机

1)、VMWare、VirtualBox(安装);

2)、导入虚拟机文件centos7.ova文件;

3)、双击启动linux虚拟机;使用 root/ 123456登陆;

4)、使用客户端(smarTTy或者xshell)连接linux服务器进行命令操作;

5)、设置虚拟机网络;

桥接网络===选好网卡===接入网线;

6)、设置好网络以后使用命令重启虚拟机的网络

7)、查看linux的ip地址

8)、使用客户端连接linux;

2)、在linux虚拟机上安装docker

几个关键命令:

具体安装教程网络上有,我的是Deepin环境,找到一篇不错的教程:

https://blog.csdn.net/qq_36148847/article/details/79273591

4、Docker常用命令&操作

1)、镜像操作

操作命令说明
检索docker search 关键字 eg:docker search redis我们经常去docker hub上检索镜像的详细信息,如镜像的TAG。
拉取docker pull 镜像名:tag:tag是可选的,tag表示标签,多为软件的版本,默认是latest
列表docker images查看所有本地镜像
删除docker rmi image-id删除指定的本地镜像

官方仓库: https://hub.docker.com/

2)、容器操作

软件镜像(QQ安装程序)----运行镜像----产生一个容器(正在运行的软件,运行的QQ);

步骤:

 

操作命令说明
运行docker run --name container-name -d image-name
eg:docker run ––name myredis –d redis
--name:自定义容器名
-d:后台运行
image-name : 指定镜像模板
列表docker ps(查看运行中的容器);加上-a;可以查看所有容器
停止docker stop container-name/container-id停止当前你运行的容器
启动docker start container-name/container-id启动容器
删除docker rm container-id删除指定容器
端口映射-p 6379:6379
eg:docker run -d -p 6379:6379 --name myredis docker.io/redis
-p: 主机端口(映射到)容器内部的端口
容器日志docker logs container-name/container-id 

其中container-name表示容器的名字,container-id表示容器的id;

更多命令: https://docs.docker.com/engine/reference/commandline/docker/

 

3)、安装MySQL示例

错误的启动

正确的启动(还是不能使用,没有做映射)

做了端口映射-p 3306:3306

几个其他的高级操作(详细参考官方文档)


六、SpringBoot与数据访问

1、JDBC

pom.xml基本配置:

application.yml简单配置:

效果:

自动配置原理都在这个包下:org.springframework.boot.autoconfigure.jdbc

1、参考DataSourceConfiguration,根据配置创建数据源,SpringBoot1.0X默认使用Tomcat连接池、SpringBoot2.0X默认使用HikariDataSource数据源。

2、可以使用spring.datasource.type指定自定义的数据源类型;

3、SpringBoot默认可以支持

4、自定义数据源类型

5、DataSourceAutoConfiguration中的DataSourceInitializer(是一个ApplicationListener)

作用:

默认只需要将文件命名为下面的方式,启动项目就会自动根据SQL文件创建表。(一定要是SpringBoot.10XX)

注意如果是SpringBoot2.0X在启动的时候如果要创建数据表,要添加一句:initialization-mode: always #

默认配置的相关源码:

6、操作数据库:自动配置了JdbcTemplate操作数据库;

JDBCTemplate简单测试:

编写的Controller:

2、整合Druid数据源

项目:springboot_06_data_druid

启动报错问题解决博客:

博客: https://blog.csdn.net/xingkongtianma01/article/details/81624313

改变默认的数据源需要配置type属性:

Druid的相关配置:

效果:

3、整合Mybatis

pom.xml导入依赖:

mybatis-starter的依赖图:

步骤:

1)、配置数据源相关属性;(见上一节Druid)

2)、给数据库建表;

3)、创建JavaBean

1)、注解版

项目: springboot_06_data_mybatis

只需要编写Mapper即可。

Controller:

测试:

自定义的规则:在Configuration中编写ConfigurationCustomizer即可(自定义Mybatis的配置规则)。

可以将@MapperScan标注在主配置类中,这样就不需要在所有的Mapper接口上都标注@Mapper注解了。

2)、配置文件版

EmployeeMapper.xml配置:

mybatis-config主配置文件:

application.yml配置:

编写Controller测试:

测试结果:

4、整合SprintData JPA

1)、SpringData简介

2)、整合SpringData JPA

JPA:ORM(Object Relational Mapping), 操作步骤如下:

1)、编写一个实体类(bean)和数据表进行映射,并且配置好映射关系;

这里的表不需要自己手动创建,JPA会自动创建。

2)、编写一个Dao接口来操作实体类对应的数据表(Repository)(有一些自动的方法,所以这里啥也不需要写)