目录

  • 初识Spring Boot
  • Spring boot 入门
      • 系统要求
      • Maven配置文件
      • HelloWorld项目
      • 创建maven工程
      • 引入依赖
      • 创建主程序
      • 编写业务
      • 运行&测试
      • 设置配置
      • 打包部署
    • SpringBoot应用如何编写【实战】
      • SpringBoot入门程序制作(一)
      • SpringBoot入门程序制作(二)
      • SpringBoot入门程序制作(三)
      • SpringBoot入门程序制作(四)
      • 教你一招:在Idea中隐藏指定文件/文件夹
      • 教你一招:lombok简化开发
  • Spring Boot特性
    • 依赖管理的特性
    • 自动配置的特性
  • 底层注解
    • 底层注解-@Configuration详解
    • 底层注解-@Import导入组件
    • 底层注解-@Conditional条件装配
    • 底层注解-@ImportResource导入Spring配置文件
    • 底层注解-@ConfigurationProperties配置绑定
  • 底层运行原理
    • 自动配置【源码分析】-自动包规则原理
      • @SpringBootConfiguration
      • @ComponentScan
      • @EnableAutoConfiguration
      • @AutoConfigurationPackage
    • 自动配置【源码分析】-初始加载自动配置类
      • @Import(AutoConfigurationImportSelector.class)
    • 自动配置【源码分析】-自动配置流程
    • yaml文件配置
      • 基本语法
      • 数据类型
      • 实例
    • yaml数据读取
      • 读取单一数据
      • 读取全部数据
      • 读取对象数据
      • yaml文件中的数据引用
      • yaml注入配置文件
  • 开发场景—WEB
    • WEB开发简介
    • WEB开发场景-静态资源规则与定制化
      • 静态资源目录
      • 静态资源访问前缀
      • webjar
      • 欢迎页支持
      • 自定义Favicon
    • WEB开发组件
      • 拦截器
      • Servlet
      • 过滤器Filter
      • 字符集过滤器
    • WEB开发应用-视图解析Thymeleaf
      • thymeleaf介绍
      • thymeleaf使用
        • 引入Starter
        • 自动配置好了thymeleaf
      • 基本语法
        • 表达式
        • Thymeleaf属性
        • 字面量
        • 文本操作
        • 数学运算
        • 布尔运算
        • 比较运算
        • 条件运算
      • 特殊操作-设计属性值
        • each
        • th:if
        • th:switch
        • th:inline
        • 设置属性值-th:attr
      • 迭代
      • 条件运算
      • 属性优先级
      • 内置对象
      • 内置工具类
      • 自定义模板
  • 开发场景—数据访问
      • 导入JDBC场景
      • 相关数据源配置类
      • 修改配置项
    • 数据访问-自定义方式整合druid数据源
      • Druid是什么?
      • 自定义方式
    • 数据访问-druid数据源starter整合方式
    • 数据访问-整合MyBatis-配置版
      • 第一种方式 : @Mapper
      • 第二种方式 : @MapperScan
      • 第三种方式: Mapper文件和Dao接口分开管理
      • 事务
      • 小结
    • 数据访问-整合MyBatis-注解配置混合版
    • 数据访问-整合MyBatisPlus操作数据库
      • MyBatisPlus是什么
  • 总结
    • 技术总结
    • 结语

初识Spring Boot

Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。
SpringBoot是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can “just run”,能迅速的开发web应用,几行代码开发一个http接口。
——————————
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景 衍生 一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
是的这就是Java企业级应用->J2EE->spring->springboot的过程。
随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件;
总的来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 ,简化了配置。
Spring Boot 出生名门,从一开始就站在一个比较高的起点,又经过这几年的发展,生态足够完善,Spring Boot 已经当之无愧成为 Java 领域最热门的技术。

总结来说优点如下:

  • 创建独立的Spring 应用
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌web容器,简化web项目
  • 提供生产级别的监控,健康检查及外部化配置
  • 无代码生成,无需编写XML

Spring boot 入门

系统要求

  • Java 8
  • Maven 3.3+
  • IntelliJ IDEA 2019.1.2

Maven配置文件

<mirrors><mirror><id>nexus-aliyun</id><mirrorOf>central</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
</mirrors><profiles><profile><id>jdk-1.8</id><activation><activeByDefault>true</activeByDefault><jdk>1.8</jdk></activation><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion></properties></profile>
</profiles>

HelloWorld项目

需求:浏览发送/hello请求,响应 “Hello,Spring Boot 2”

创建maven工程

引入依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

创建主程序

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}
}

编写业务

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@RequestMapping("/hello")public String handle01(){return "Hello, Spring Boot 2!";}
}

运行&测试

  • 运行MainApplication
  • 浏览器输入http://localhost:8888/hello,将会输出Hello, Spring Boot 2!

设置配置

maven工程的resource文件夹中创建application.properties文件。

# 设置端口号
server.port=8888

更多配置信息

打包部署

在pom.xml添加

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

在IDEA的Maven插件上点击运行 clean 、package,把helloworld工程项目的打包成jar包,

打包好的jar包被生成在helloworld工程项目的target文件夹内。

用cmd运行java -jar boot-01-helloworld-1.0-SNAPSHOT.jar,既可以运行helloworld工程项目。
将jar包直接在目标服务器执行即可。

SpringBoot应用如何编写【实战】

SpringBoot入门程序制作(一)

​ 下面使用SpringBoot技术快速构建一个SpringMVC的程序,通过这个过程体会简化二字的含义。

步骤①:创建新模块,选择Spring Initializr,并配置模块相关基础信息

特别关注:第3步点击Next时,Idea需要联网状态才可以进入到后面那一页,如果不能正常联网,就无法正确到达右面那个设置页了,会一直联网转转转。

特别关注:第5步选择java版本和你计算机上安装的JDK版本匹配即可,但是最低要求为JDK8或以上版本,推荐使用8或11。

步骤②:选择当前模块需要使用的技术集

​ 按照要求,左侧选择web,然后在中间选择Spring Web即可,选完右侧就出现了新的内容项,这就表示勾选成功了。

关注:此处选择的SpringBoot的版本使用默认的就可以了,需要说一点,SpringBoot的版本升级速度很快,可能昨天创建工程的时候默认版本是2.5.4,今天再创建工程默认版本就变成2.5.5了,差别不大,无需过于纠结,并且还可以到配置文件中修改对应的版本。

步骤③:开发控制器类

//Rest模式
@RestController
@RequestMapping("/books")
public class BookController {@GetMappingpublic String getById(){System.out.println("springboot is running...");return "springboot is running...";}
}

​ 入门案例制作的SpringMVC的控制器基于Rest风格开发,当然此处使用原始格式制作SpringMVC的程序也是没有问题的,上例中的@RestController与@GetMapping注解是基于Restful开发的典型注解。

关注:做到这里SpringBoot程序的最基础的开发已经做完了,现在就可以正常的运行Spring程序了。可能有些小伙伴会有疑惑,Tomcat服务器没有配置,Spring也没有配置,什么都没有配置这就能用吗?这就是SpringBoot技术的强大之处。关于内部工作流程后面再说,先专心学习开发过程。

步骤④:运行自动生成的Application类

​ 使用带main方法的java程序的运行形式来运行程序,运行完毕后,控制台输出上述信息。

​ 不难看出,运行的信息中包含了8080的端口,Tomcat这种熟悉的字样,难道这里启动了Tomcat服务器?是的,这里已经启动了。那服务器没有配置,哪里来的呢?后面再说。现在你就可以通过浏览器访问请求的路径,测试功能是否工作正常了。

访问路径: http://localhost:8080/books

​ 是不是感觉很神奇?当前效果其实依赖的底层逻辑还是很复杂的,但是从开发者角度来看,目前只有两个文件展现到了开发者面前。

  • pom.xml

    这是maven的配置文件,描述了当前工程构建时相应的配置信息。

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.4</version></parent><groupId>com.itheima</groupId><artifactId>springboot_01_01_quickstart</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
    </project>
    

    配置中有两个信息需要关注,一个是parent,也就是当前工程继承了另外一个工程,干什么用的后面再说,还有依赖坐标,干什么用的后面再说。

  • Application类

    @SpringBootApplication
    public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
    }
    

    这个类功能很简单,就一句代码,前面运行程序就是运行的这个类。

​ 到这里我们可以大胆推测一下,如果上面这两个文件没有的话,SpringBoot肯定没法玩,看来核心就是这两个文件了。由于是制作第一个SpringBoot程序,先不要关注这两个文件的功能,后面详细讲解内部工作流程。

​ 通过上面的制作,我们不难发现,SpringBoot程序简直太好写了,几乎什么都没写,功能就有了,这也是SpringBoot技术为什么现在这么火的原因,和Spring程序相比,SpringBoot程序在开发的过程中各个层面均具有优势。

类配置文件 Spring SpringBoot
pom文件中的坐标 手工添加 勾选添加
web3.0配置类 手工制作
Spring/SpringMVC配置类 手工制作
控制器 手工制作 手工制作

​ 一句话总结一下就是能少写就少写能不写就不写,这就是SpringBoot技术给我们带来的好处,行了,现在你就可以动手做一做SpringBoot程序了,看看效果如何,是否真的帮助你简化开发了。

总结

  1. 开发SpringBoot程序在Idea工具中基于联网的前提下可以根据向导快速制作
  2. SpringBoot程序需要依赖JDK,版本要求最低为JDK8
  3. SpringBoot程序中需要使用某种功能时可以通过勾选的形式选择技术,也可以手工添加对应的要使用的技术(后期讲解)
  4. 运行SpringBoot程序通过运行Application程序进行

思考

前面制作的时候说过,这个过程必须联网才可以进行,但是有些时候你会遇到一些莫名其妙的问题,比如基于Idea开发时,你会发现你配置了一些坐标,然后Maven下载对应东西的时候死慢死慢的,甚至还会失败。其实这种现象和Idea这款IDE工具有关,万一Idea不能正常访问网络的话,我们是不是就无法制作SpringBoot程序了呢?咱们下一节再说。

SpringBoot入门程序制作(二)

如果Idea不能正常联网,这个SpringBoot程序就无法制作了吗?开什么玩笑,世上IDE工具千千万,难道SpringBoot技术还必须基于Idea来做了?这是不可能的。开发SpringBoot程序可以不基于IDE工具进行,在SpringBoot官网中可以直接创建SpringBoot程序。

​ SpringBoot官网和Spring的官网是在一起的,都是 spring.io 。你可以通过项目一级一级的找到SpringBoot技术的介绍页,然后在页面中间部位找到如下内容

步骤①:点击Spring Initializr后进入到创建SpringBoot程序界面,接下来就是输入信息的过程,和在Idea中制作是一样的,只是界面发生了变化,根据自己的要求,在左侧选择对应信息和输入对应的信息。

步骤②:右侧的ADD DEPENDENCIES用于选择使用何种技术,和之前勾选的Spring WEB是在做同一件事,仅仅是界面不同而已,点击后打开网页版的技术选择界面。

步骤③:所有信息设置完毕后,点击下面左侧GENERATE按钮,生成一个文件包。

步骤④:保存后得到一个压缩文件,这个文件就是创建的SpringBoot工程

步骤⑤:解压缩此文件得到工程目录,在Idea中导入即可直接使用,和之前在Idea环境下根据向导创建的工程完全一样,你可以创建一个Controller测试一下当前工程是否可用。

温馨提示

​ 做到这里其实可以透漏一个小秘密,Idea工具中创建SpringBoot工程其实连接的就是SpringBoot的官网,还句话说这种方式和第一种方式是一模一样的,只不过Idea把界面给整合了一下,读取Spring官网信息,然后展示到Idea界面中而已,可以通过如下信息比对一下

Idea中创建工程时默认选项

SpringBoot官网创建工程时对应的地址

​ 看看SpringBoot官网创建工程的URL地址,是不是和Idea中使用的URL地址是一样的?

总结

  1. 打开SpringBoot官网,选择Quickstart Your Project中的Spring Initializr。

  2. 创建工程。

  3. 保存项目文件。

  4. 解压项目,通过IDE导入项目后进行编辑使用。

思考

现在创建工程靠的是访问国外的Spring主站,但是互联网信息的访问是可以被约束的,如果一天这个网站你在国内无法访问了,那前面这两种方式就无法创建SpringBoot工程了,这时候又该怎么解决这个问题呢?咱们下一节再说。

SpringBoot入门程序制作(三)

前面提到网站如果被限制访问了,该怎么办?开动脑筋想一想,不管是方式一还是方式二其实走的都是同一个路线,就是通过SpringBoot官网创建SpringBoot工程,假如国内有这么一个网站也能提供这样的功能,是不是就解决了呢?必然的嘛,新的问题又来了,国内有提供这样功能的网站吗?还真有,阿里提供了一个,下面问题就简单了,网址告诉我们就OK了,没错,就是这样。

​ 创建工程时,切换选择starter服务路径,然后手工输入阿里云地址即可,地址:http://start.aliyun.com或https://start.aliyun.com

​ 阿里为了便于自己公司开发使用,特此在依赖坐标中添加了一些阿里自主的技术,也是为了推广自己的技术吧,所以在依赖选择列表中,你有了更多的选择。此外,阿里提供的地址更符合国内开发者的使用习惯,里面有一些SpringBoot官网上没有给出的坐标,大家可以好好看一看。

​ 不过有一点需要说清楚,阿里云地址默认创建的SpringBoot工程版本是2.4.1,所以如果你想更换其他的版本,创建项目后在pom文件中手工修改即可,别忘了刷新一下,加载新版本信息。

注意:阿里云提供的工程创建地址初始化完毕后和使用SpringBoot官网创建出来的工程略有区别,主要是在配置文件的形式上有区别,这个信息在后面讲解SpringBoot程序的执行流程时给大家揭晓。

总结

  1. 选择start来源为自定义URL
  2. 输入阿里云starter地址
  3. 创建项目

思考

做到这里我们已经有了三种方式创建SpringBoot工程,但是每种方式都要求你必须能上网才能创建工程。假如有一天,你加入了一个保密级别比较高的项目组,整个项目组没有外网,这个事情是不是就不能做了呢?咱们下一节再说。

SpringBoot入门程序制作(四)

不能上网,还想创建SpringBoot工程,能不能做呢?能做,但是你要先问问自己联网和不联网到底差别是什么?这个差别找到以后,你就发现,你把联网要干的事情都提前准备好,就无需联网了。

​ 联网做什么呢?首先SpringBoot工程也是基于Maven构建的,而Maven工程中如果加载一些工程需要使用又不存在的东西时,就要联网去下载。其实SpringBoot工程创建的时候就是要去下载一些必要的组件。如果把这些东西提前准备好呢?是的,就是这样。

​ 下面就手工创建一个SpringBoot工程,如果需要使用的东西提前保障在maven仓库中存在,整个过程就可以不依赖联网环境了。不过咱们已经用3种方式创建了SprongBoot工程了,所以下面也没什么东西需要下载了。

步骤①:创建工程时,选择创建普通Maven工程。

步骤②:参照标准SpringBoot工程的pom文件,书写自己的pom文件即可。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.4</version></parent><groupId>com.itheima</groupId><artifactId>springboot_01_04_quickstart</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

​ 用什么写什么,不用的都可以不写。当然,现在小伙伴们可能还不知道用什么和不用什么,最简单的就是复制粘贴了,随着后面的学习,你就知道哪些可以省略了。此处我删减了一些目前不是必须的东西,一样能用。核心的内容有两条,一个是继承了一个父工程,另外添加了一个依赖。

步骤③:之前运行SpringBoot工程需要一个类,这个缺不了,自己手写一个就行了,建议按照之前的目录结构来创建,先别玩花样,先学走后学跑。类名可以自定义,关联的名称同步修改即可。

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);}
}

关注:类上面的注解@SpringBootApplication千万别丢了,这个是核心,后面再介绍。

关注:类名可以自定义,只要保障下面代码中使用的类名和你自己定义的名称一样即可,也就是run方法中的那个class对应的名称。

步骤④:下面就可以自己创建一个Controller测试一下是否能用了,和之前没有差别的。

​ 看到这里其实应该能够想明白了,通过向导或者网站创建的SpringBoot工程其实就是帮你写了一些代码,而现在是自己手写,写的内容都一样,仅此而已。

温馨提示

​ 如果你的计算机上从来没有创建成功过SpringBoot工程,自然也就没有下载过SpringBoot对应的坐标相关的资源,那用手写创建的方式在不联网的情况下肯定该是不能用的。所谓手写,其实就是自己写别人帮你生成的东西,但是引用的坐标对应的资源必须保障maven仓库里面有才行,如果没有,还是要去下载的。

总结

  1. 创建普通Maven工程
  2. 继承spring-boot-starter-parent
  3. 添加依赖spring-boot-starter-web
  4. 制作引导类Application

​ 到这里已经学习了4种创建SpringBoot工程的方式,其实本质是一样的,都是根据SpringBoot工程的文件格式要求,通过不同时方式生成或者手写得到对应的文件,效果完全一样。

教你一招:在Idea中隐藏指定文件/文件夹

​ 创建SpringBoot工程时,使用SpringBoot向导也好,阿里云也罢,其实都是为了一个目的,得到一个标准的SpringBoot工程文件结构。这个时候就有新的问题出现了,标准的工程结构中包含了一些未知的文件夹,在开发的时候看起来特别别扭,这一节就来说说这些文件怎么处理。

​ 处理方案无外乎两种,如果你对每一个文件/目录足够了解,有用的留着,没有用的完全可以删除掉。或者不删除,但是看着别扭,就设置文件为看不到就行了。删除不说了,选中后直接Delete掉就好了,这一节说说如何隐藏指定的文件或文件夹信息。

​ 既然是在Idea下做隐藏功能,肯定隶属于Idea的设置,设置方式如下。

步骤①:打开设置,【Files】→【Settings】。

步骤②:打开文件类型设置界面后,【Editor】→【File Types】→【Ignored Files and Folders】,忽略文件或文件夹显示。

步骤③:添加你要隐藏的文件名称或文件夹名称,可以使用*号通配符,表示任意,设置完毕即可。

​ 到这里就做完了,其实就是Idea的一个小功能

总结

  1. Idea中隐藏指定文件或指定类型文件

    1. 【Files】→【Settings】
    2. 【Editor】→【File Types】→【Ignored Files and Folders】
    3. 输入要隐藏的名称,支持*号通配符
    4. 回车确认添加

教你一招:lombok简化开发

Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码。
spring boot已经管理Lombok。引入依赖:

 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>

IDEA中File->Settings->Plugins,搜索安装Lombok插件。


简化日志开发

@Slf4j
@RestController
public class HelloController {@RequestMapping("/hello")public String handle01(@RequestParam("name") String name){log.info("请求进来了....");return "Hello, Spring Boot 2!"+"你好:"+name;}
}

Spring Boot特性

依赖管理的特性

  • 父项目做依赖管理
依赖管理
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version>
</parent>上面项目的父项目如下:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.4.RELEASE</version>
</parent>它几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制
  • 开发导入starter场景启动器

    1. 见到很多 spring-boot-starter-* : *就某种场景
    2. 只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
    3. 更多SpringBoot所有支持的场景
    4. 见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
所有场景启动器最底层的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.3.4.RELEASE</version><scope>compile</scope>
</dependency>
  • 无需关注版本号,自动版本仲裁

    1. 引入依赖默认都可以不写版本
    2. 引入非版本仲裁的jar,要写版本号。
  • 可以修改默认版本号

    1. 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
    2. 在当前项目里面重写配置,如下面的代码。
<properties><mysql.version>5.1.43</mysql.version>
</properties>

IDEA快捷键:

  • ctrl + shift + alt + U:以图的方式显示项目中依赖之间的关系。
  • alt + ins:相当于Eclipse的 Ctrl + N,创建新类,新包等。

自动配置的特性

  • 自动配好Tomcat

    • 引入Tomcat依赖。
    • 配置Tomcat
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>2.3.4.RELEASE</version><scope>compile</scope>
</dependency>
  • 自动配好SpringMVC

    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(功能)
  • 自动配好Web常见功能,如:字符编码问题

    • SpringBoot帮我们配置好了所有web开发的常见场景
public static void main(String[] args) {//1、返回我们IOC容器ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);//2、查看容器里面的组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}
}
  • 默认的包结构

    • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径
      • @SpringBootApplication(scanBasePackages=“com.lun”)
      • @ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.lun")
  • 各种配置拥有默认值

    • 默认配置最终都是映射到某个类上,如:MultipartProperties
    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
  • 按需加载所有自动配置项

    • 非常多的starter
    • 引入了哪些场景这个场景的自动配置才会开启
    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

底层注解

底层注解-@Configuration详解

  • 基本使用

    • Full模式与Lite模式
    • 示例
/*** 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的* 2、配置类本身也是组件* 3、proxyBeanMethods:代理bean的方法*      Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)*      Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)*/
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {/*** Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象* @return*/@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例public User user01(){User zhangsan = new User("zhangsan", 18);//user组件依赖了Pet组件zhangsan.setPet(tomcatPet());return zhangsan;}@Bean("tom")public Pet tomcatPet(){return new Pet("tomcat");}
}

@Configuration测试代码如下:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.likme.boot")
public class MainApplication {public static void main(String[] args) {//1、返回我们IOC容器ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);//2、查看容器里面的组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}//3、从容器中获取组件Pet tom01 = run.getBean("tom", Pet.class);Pet tom02 = run.getBean("tom", Pet.class);System.out.println("组件:"+(tom01 == tom02));//4、com.likme.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892MyConfig bean = run.getBean(MyConfig.class);System.out.println(bean);//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。//保持组件单实例User user = bean.user01();User user1 = bean.user01();System.out.println(user == user1);User user01 = run.getBean("user01", User.class);Pet tom = run.getBean("tom", Pet.class);System.out.println("用户的宠物:"+(user01.getPet() == tom));}
}
  • 最佳实战

    • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
    • 配置 类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)

lite 英 [laɪt] 美 [laɪt]
adj. 低热量的,清淡的(light的一种拼写方法);类似…的劣质品


IDEA快捷键:

  • Alt + Ins:生成getter,setter、构造器等代码。
  • Ctrl + Alt + B:查看类的具体实现代码。

底层注解-@Import导入组件

@Bean、@Component、@Controller、@Service、@Repository,它们是Spring的基本标签,在Spring Boot中并未改变它们原来的功能。

@ComponentScan 在之前将特性时有用例。

@Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {}

测试类:


//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);//...//5、获取组件
String[] beanNamesForType = run.getBeanNamesForType(User.class);for (String s : beanNamesForType) {System.out.println(s);
}DBHelper bean1 = run.getBean(DBHelper.class);
System.out.println(bean1);

底层注解-@Conditional条件装配

条件装配:满足Conditional指定的条件,则进行组件注入

用@ConditionalOnMissingBean举例说明

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "tom")//没有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {@Beanpublic User user01(){User zhangsan = new User("zhangsan", 18);zhangsan.setPet(tomcatPet());return zhangsan;}@Bean("tom22")public Pet tomcatPet(){return new Pet("tomcat");}
}public static void main(String[] args) {//1、返回我们IOC容器ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);//2、查看容器里面的组件String[] names = run.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}boolean tom = run.containsBean("tom");System.out.println("容器中Tom组件:"+tom);//falseboolean user01 = run.containsBean("user01");System.out.println("容器中user01组件:"+user01);//trueboolean tom22 = run.containsBean("tom22");System.out.println("容器中tom22组件:"+tom22);//true}

底层注解-@ImportResource导入Spring配置文件

比如,公司使用bean.xml文件生成配置bean,然而你为了省事,想继续复用bean.xml,@ImportResource粉墨登场。

bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans ..."><bean id="haha" class="com.lun.boot.bean.User"><property name="name" value="zhangsan"></property><property name="age" value="18"></property></bean><bean id="hehe" class="com.lun.boot.bean.Pet"><property name="name" value="tomcat"></property></bean>
</beans>

使用方法:

@ImportResource("classpath:beans.xml")
public class MyConfig {...
}

测试类:

public static void main(String[] args) {//1、返回我们IOC容器ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);boolean haha = run.containsBean("haha");boolean hehe = run.containsBean("hehe");System.out.println("haha:"+haha);//trueSystem.out.println("hehe:"+hehe);//true
}

底层注解-@ConfigurationProperties配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用

传统方法:

public class getProperties {public static void main(String[] args) throws FileNotFoundException, IOException {Properties pps = new Properties();pps.load(new FileInputStream("a.properties"));Enumeration enum1 = pps.propertyNames();//得到配置文件的名字while(enum1.hasMoreElements()) {String strKey = (String) enum1.nextElement();String strValue = pps.getProperty(strKey);System.out.println(strKey + "=" + strValue);//封装到JavaBean。}}}

Spring Boot一种配置配置绑定:

@ConfigurationProperties + @Component

假设有配置文件application.properties

mycar.brand=BYD
mycar.price=100000

只有在容器中的组件,才会拥有SpringBoot提供的强大功能

@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {...
}

Spring Boot另一种配置配置绑定:

@EnableConfigurationProperties + @ConfigurationProperties

  1. 开启Car配置绑定功能
  2. 把这个Car这个组件自动注册到容器中
@EnableConfigurationProperties(Car.class)
public class MyConfig {...
}
@ConfigurationProperties(prefix = "mycar")
public class Car {...
}

底层运行原理

自动配置【源码分析】-自动包规则原理

Spring Boot应用的启动类:

@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}}

分析下@SpringBootApplication

@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 {...
}

重点分析@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

进入这个注解:可以看到上面还有很多其他注解!

@SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
@Configuration代表当前是一个配置类。
作用: 这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目2、查找并加载所有可用初始化器 , 设置到initializers属性中3、找出所有的应用程序监听器,设置到listeners属性中4、推断并设置main方法的定义类,找到运行的主类

我们继续进去这个注解查看
SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

@ComponentScan

指定扫描哪些Spring注解。
这个注解在Spring中很重要 ,它对应XML配置中的元素。
作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@ComponentScan 在07、基础入门-SpringBoot-自动配置特性有用例。

@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}

重点分析@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)
作用:开启自动配置功能
以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

点进注解接续查看:

@AutoConfigurationPackage

标签名直译为:自动配置包,指定了默认的包规则。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)//给容器中导入一个组件
public @interface AutoConfigurationPackage {String[] basePackages() default {};Class<?>[] basePackageClasses() default {};
}
  1. 利用Registrar给容器中导入一系列组件
  2. 将指定的一个包下的所有组件导入进MainApplication所在包下。

自动配置【源码分析】-初始加载自动配置类

@Import(AutoConfigurationImportSelector.class)

  1. 利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
  2. 调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
  3. 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
  4. META-INF/spring.factories位置来加载一个文件。
    • 默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
    • spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

# 文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
# spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
...

虽然我们127个场景的所有自动配置启动的时候默认全部加载,但是xxxxAutoConfiguration按照条件装配规则(@Conditional),最终会按需配置。
AopAutoConfiguration类:

@Configuration(proxyBeanMethods = false
)
@ConditionalOnProperty(prefix = "spring.aop",name = "auto",havingValue = "true",matchIfMissing = true
)
public class AopAutoConfiguration {public AopAutoConfiguration() {}...
}

作用:给容器中导入一个组件
Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

自动配置【源码分析】-自动配置流程

DispatcherServletAutoConfiguration的内部类DispatcherServletConfiguration为例子:

@Bean
@ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范// Detect if the user has created a MultipartResolver but named it incorrectlyreturn resolver;//给容器中加入了文件上传解析器;
}

SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先

总结

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。(xxxxProperties里面读取,xxxProperties和配置文件进行了绑定)
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties

yaml文件配置

同以前的properties用法

YAML 是 “YAML Ain’t Markup Language”(YAML不是一种标记语言 )的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。

这种语言以数据作为中心,而不是以标记语言为重点!

非常适合用来做以数据为中心的配置文件

基本语法

  • key: value;kv之间有空格

  • 大小写敏感

  • 使用缩进表示层级关系

  • 缩进的空格数不重要,只要相同层级的元素左对齐即可

  • '#'表示注释

  • 字符串无需加引号,如果要加,单引号’'、双引号""表示字符串内容会被 转义、不转义

  • 属性层级关系使用多行描述,每行结尾使用冒号结束

  • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)

  • 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)

上述规则不要死记硬背,按照书写习惯慢慢适应,并且在Idea下由于具有提示功能,慢慢适应着写格式就行了。核心的一条规则要记住,数据前面要加空格与冒号隔开

boolean: TRUE                        #TRUE,true,True,FALSE,false,False均可
float: 3.14                         #6.8523015e+5  #支持科学计数法
int: 123                            #0b1010_0111_0100_1010_1110    #支持二进制、八进制、十六进制
null: ~                             #使用~表示null
string: HelloWorld                  #字符串可以直接书写
string2: "Hello World"            #可以使用双引号包裹特殊字符
date: 2022-10-01                    #日期必须使用yyyy-MM-dd格式
datetime: 2022-10-17T15:02:31+08:00  #时间和日期之间使用T连接,最后使用+代表时区

数据类型

  • 字面量:单个的、不可再分的值。date、boolean、string、number、null
k: v
  • 对象:键值对的集合。map、hash、set、object
#行内写法:  k: {k1:v1,k2:v2,k3:v3}#或k: k1: v1k2: v2k3: v3
  • 数组:一组按次序排列的值。array、list、queue
#行内写法:  k: [v1,v2,v3]#或者k:- v1- v2- v3

实例

@Data
public class Person {private String userName;private Boolean boss;private Date birth;private Integer age;private Pet pet;private String[] interests;private List<String> animal;private Map<String, Object> score;private Set<Double> salarys;private Map<String, List<Pet>> allPets;
}@Data
public class Pet {private String name;private Double weight;
}

用yaml表示以上对象

person:userName: zhangsanboss: falsebirth: 2019/12/12 20:12:33age: 18pet: name: tomcatweight: 23.4interests: [篮球,游泳]animal: - jerry- marioscore:english: first: 30second: 40third: 50math: [131,140,148]chinese: {first: 128,second: 136}salarys: [3999,4999.98,5999.99]allPets:sick:- {name: tom}- {name: jerry,weight: 47}health: [{name: mario,weight: 47}]

思考

​ 现在我们已经知道了yaml具有严格的数据格式要求,并且已经可以正确的书写yaml文件了,那这些文件书写后其实是在定义一些数据。这些数据是给谁用的呢?大部分是SpringBoot框架内部使用,但是如果我们想配置一些数据自己使用,能不能用呢?答案是可以的,那如何读取yaml文件中的数据呢?咱们下一节再说。

yaml数据读取

对于yaml文件中的数据,其实你就可以想象成这就是一个小型的数据库,里面保存有若干数据,每个数据都有一个独立的名字,如果你想读取里面的数据,肯定是支持的,yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!下面就介绍3种读取数据的方式。

读取单一数据

​ yaml中保存的单个数据,可以使用Spring中的注解@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名……}

​ 记得使用@Value注解时,要将该注解写在某一个指定的Spring管控的bean的属性名上方,这样当bean进行初始化时候就可以读取到对应的单一数据了。

总结

  1. 使用@Value配合SpEL读取单个数据
  2. 如果数据存在多层级,依次书写层级名称即可

读取全部数据

​ 读取单一数据可以解决读取数据的问题,但是如果定义的数据量过大,这么一个一个书写肯定会累死人的,SpringBoot提供了一个对象,能够把所有的数据都封装到这一个对象中,这个对象叫做Environment,使用自动装配注解可以将所有的yaml数据封装到这个对象中

​ 数据封装到了Environment对象中,获取属性时,通过Environment的接口操作进行,具体方法是getProperties(String),参数填写属性名即可

总结

  1. 使用Environment对象封装全部配置信息
  2. 使用@Autowired自动装配数据到Environment对象中

读取对象数据

​ 单一数据读取书写比较繁琐,全数据读取封装的太厉害了,每次拿数据还要一个一个的getProperties(),总之用起来都不是很舒服。由于Java是一个面向对象的语言,很多情况下,我们会将一组数据封装成一个对象。SpringBoot也提供了可以将一组yaml对象数据封装一个Java对象的操作

​ 首先定义一个对象,并将该对象纳入Spring管控的范围,也就是定义成一个bean,然后使用注解@ConfigurationProperties指定该对象加载哪一组yaml中配置的信息。

​ 这个@ConfigurationProperties必须告诉他加载的数据前缀是什么,这样指定前缀下的所有属性就封装到这个对象中。记得数据属性名要与对象的变量名一一对应啊,不然没法封装。其实以后如果你要定义一组数据自己使用,就可以先写一个对象,然后定义好属性,下面到配置中根据这个格式书写即可。

温馨提示

​ 细心的小伙伴会发现一个问题,自定义的这种数据在yaml文件中书写时没有弹出提示,咱们到原理篇再揭秘如何弹出提示。

总结

  1. 使用@ConfigurationProperties注解绑定配置信息到封装类中
  2. 封装类需要定义为Spring管理的bean,否则无法进行属性注入

yaml文件中的数据引用

​ 如果你在书写yaml数据时,经常出现如下现象,比如很多个文件都具有相同的目录前缀

center:dataDir: /usr/local/fire/datatmpDir: /usr/local/fire/tmplogDir: /usr/local/fire/logmsgDir: /usr/local/fire/msgDir

​ 或者

center:dataDir: D:/usr/local/fire/datatmpDir: D:/usr/local/fire/tmplogDir: D:/usr/local/fire/logmsgDir: D:/usr/local/fire/msgDir

​ 这个时候你可以使用引用格式来定义数据,其实就是搞了个变量名,然后引用变量了,格式如下:

baseDir: /usr/local/fire
center:dataDir: ${baseDir}/datatmpDir: ${baseDir}/tmplogDir: ${baseDir}/logmsgDir: ${baseDir}/msgDir

​ 还有一个注意事项,在书写字符串时,如果需要使用转义字符,需要将数据字符串使用双引号包裹起来

lesson: "Spring\tboot\nlesson"

总结

  1. 在配置文件中可以使用${属性名}方式引用属性值
  2. 如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析

yaml注入配置文件

1、在springboot项目中的resources目录下新建一个文件 application.yml

2、编写一个实体类 Dog;

package com.kuang.springboot.pojo;@Component  //注册bean到容器中
public class Dog {private String name;private Integer age;//有参无参构造、get、set方法、toString()方法
}

3、思考,我们原来是如何给bean注入属性值的!@Value,给狗狗类测试一下:

@Component //注册bean
public class Dog {@Value("阿黄")private String name;@Value("18")private Integer age;
}
4、在SpringBoot的测试类下注入狗狗输出一下;@SpringBootTest
class DemoApplicationTests {@Autowired //将狗狗自动注入进来Dog dog;@Testpublic void contextLoads() {System.out.println(dog); //打印看下狗狗对象}}

结果成功输出,@Value注入成功,这是我们原来的办法对吧。

5、我们在编写一个复杂一点的实体类:Person 类

@Component //注册bean到容器中
public class Person {private String name;private Integer age;private Boolean happy;private Date birth;private Map<String,Object> maps;private List<Object> lists;private Dog dog;//有参无参构造、get、set方法、toString()方法
}

6、我们来使用yaml配置的方式进行注入,大家写的时候注意区别和优势,我们编写一个yaml配置!

person:name: qinjiangage: 3happy: falsebirth: 2000/01/01maps: {k1: v1,k2: v2}lists:- code- girl- musicdog:name: 旺财age: 1

7、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!

/*
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/
@Component //注册bean
@ConfigurationProperties(prefix = "person")
public class Person {private String name;private Integer age;private Boolean happy;private Date birth;private Map<String,Object> maps;private List<Object> lists;private Dog dog;
}

8、IDEA 提示,springboot配置注解处理器没有找到,让我们看文档,我们可以查看文档,找到一个依赖!

<!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

9、确认以上配置都OK之后,我们去测试类中测试一下:

@SpringBootTest
class DemoApplicationTests {@AutowiredPerson person; //将person自动注入进来@Testpublic void contextLoads() {System.out.println(person); //打印person信息}}

结果:所有值全部注入成功!

yaml配置注入到实体类完全OK!

1、将配置文件的key 值 和 属性的值设置为不一样,则结果输出为null,注入失败

2、在配置一个person2,然后将 @ConfigurationProperties(prefix = “person2”) 指向我们的person2;

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

@configurationProperties:默认从全局配置文件中获取值;

1、我们去在resources目录下新建一个person.properties文件

name=kuangshen
2、然后在我们的代码中指定加载person.properties文件

@PropertySource(value = "classpath:person.properties")
@Component //注册bean
public class Person {@Value("${name}")private String name;......
}

3、再次输出测试一下:指定配置文件绑定成功!

配置文件占位符
配置文件还可以编写占位符生成随机数

person:name: qinjiang${random.uuid} # 随机uuidage: ${random.int}  # 随机inthappy: falsebirth: 2000/01/01maps: {k1: v1,k2: v2}lists:- code- girl- musicdog:name: ${person.hello:other}_旺财age: 1

回顾properties配置
我们上面采用的yaml方法都是最简单的方式,开发中最常用的;也是springboot所推荐的!那我们来唠唠其他的实现方式,道理都是相同的;写还是那样写;配置文件除了yml还有我们之前常用的properties , 我们没有讲,我们来唠唠!

**【注意】**properties配置文件在写中文的时候,会有乱码 , 我们需要去IDEA中设置编码格式为UTF-8;

settings–>FileEncodings 中配置;

测试步骤:

1、新建一个实体类User

@Component //注册bean
public class User {private String name;private int age;private String sex;
}
2、编辑配置文件 user.propertiesuser1.name=kuangshen
user1.age=18
user1.sex=男
3、我们在User类上使用@Value来进行注入!@Component //注册bean
@PropertySource(value = "classpath:user.properties")
public class User {//直接使用@value@Value("${user.name}") //从配置文件中取值private String name;@Value("#{9*2}")  // #{SPEL} Spring表达式private int age;@Value("男")  // 字面量private String sex;
}
4、Springboot测试@SpringBootTest
class DemoApplicationTests {@AutowiredUser user;@Testpublic void contextLoads() {System.out.println(user);}}

结果正常输出:

对比小结

@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;

  1. @ConfigurationProperties只需要写一次即可 , @Value则需要每个字段都添加
  2. 松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastName是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
  3. JSR303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性
  4. 复杂类型封装,yml中可以封装对象 , 使用value就不支持

结论:

配置yml和配置properties都可以获取到值 , 强烈推荐 yml;

如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;

如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!

开发场景—WEB

WEB开发简介

在进行项目编写前,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。
只有把这些都搞清楚了,我们在之后使用才会更加得心应手。途径一:源码分析,途径二:官方文档!

https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景我们都无需自定义配置)

The auto-configuration adds the following features on top of Spring’s defaults:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

    • 内容协商视图解析器和BeanName视图解析器

    自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器,ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的

即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

  • 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
  • Support for HttpMessageConverters (covered later in this document).

    • 支持 HttpMessageConverters (后来我们配合内容协商理解原理)
  • Automatic registration of MessageCodesResolver (covered later in this document).

    • 自动注册 MessageCodesResolver (国际化用)
  • Static index.html support.

    • 静态index.html 页支持
  • Custom Favicon support (covered later in this document).

    • 自定义 Favicon
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

    • 自动使用 ConfigurableWebBindingInitializer ,(DataBinder负责将请求数据绑定到JavaBean上)

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

不用@EnableWebMvc注解。使用 @Configuration + WebMvcConfigurer 自定义规则

If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

声明 WebMvcRegistrations 改变默认底层组件

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

使用 @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC

总结

  • 这么多的自动配置,原理都是一样的,通过这个WebMVC的自动配置原理分析,我们要学会一种学习方式,通过源码探究,得出结论;这个结论一定是属于自己的,而且一通百通。

  • SpringBoot的底层,大量用到了这些设计细节思想,所以,没事需要多阅读源码!得出结论;

  • SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;

  • 如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!

WEB开发场景-静态资源规则与定制化

静态资源目录

只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources

访问 : 当前项目根路径/ + 静态资源名

原理: 静态映射/**。

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面。

也可以改变默认的静态资源路径,/static/public,/resources, /META-INF/resources失效

resources:static-locations: [classpath:/haha/]

静态资源访问前缀

spring:mvc:static-path-pattern: /res/**

当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找

webjar

可用jar方式添加css,js等资源文件,

https://www.webjars.org/

例如,添加jquery

<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.5.1</version>
</dependency>

访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径。
官方文档

欢迎页支持

  • 静态资源路径下 index.html。

    • 可以配置静态资源路径
    • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致welcome page功能失效resources:static-locations: [classpath:/haha/]
  • controller能处理/index。

自定义Favicon

指网页标签上的小图标。

favicon.ico 放在静态资源目录下即可。

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致 Favicon 功能失效

WEB开发组件

拦截器

拦截器是SpringMVC中一种对象,能拦截器对Controller的请求。

拦截器框架中有系统的拦截器, 还可以自定义拦截器。 实现对请求预先处理。

实现自定义拦截器:

  1. 创建类实现SpringMVC框架的HandlerInterceptor接口

public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}

default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}

}

2.需在SpringMVC的配置文件中,声明拦截器```xml
<mvc:interceptors><mvc:interceptor><mvc:path="url" /><bean class="拦截器类全限定名称"/></mvc:interceptor>
</mvc:interceptors>

SpringBoot中注册拦截器:


@Configuration
public class MyAppConfig implements WebMvcConfigurer {//添加拦截器对象, 注入到容器中@Overridepublic void addInterceptors(InterceptorRegistry registry) {//创建拦截器对象HandlerInterceptor interceptor = new LoginInterceptor();//指定拦截的请求uri地址String path []= {"/user/**"};//指定不拦截的地址String excludePath  [] = {"/user/login"};registry.addInterceptor(interceptor).addPathPatterns(path).excludePathPatterns(excludePath);}
}

Servlet

在SpringBoot框架中使用Servlet对象。

使用步骤:

  1. 创建Servlet类。 创建类继承HttpServlet
  2. 注册Servlet ,让框架能找到Servlet

例子:

1.创建自定义Servlet

//创建Servlet类
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//使用HttpServletResponse输出数据,应答结果resp.setContentType("text/html;charset=utf-8");PrintWriter out  = resp.getWriter();out.println("===执行的是Servlet==");out.flush();out.close();}
}
  1. 注册Servlet
@Configuration
public class WebApplictionConfig {//定义方法, 注册Servlet对象@Beanpublic ServletRegistrationBean servletRegistrationBean(){//public ServletRegistrationBean(T servlet, String... urlMappings)//第一个参数是 Servlet对象, 第二个是url地址//ServletRegistrationBean bean =//new ServletRegistrationBean( new MyServlet(),"/myservlet");ServletRegistrationBean bean = new ServletRegistrationBean();bean.setServlet( new MyServlet());bean.addUrlMappings("/login","/test"); // <url-pattern>return bean;}
}

过滤器Filter

Filter是Servlet规范中的过滤器,可以处理请求, 对请求的参数, 属性进行调整。 常常在过滤器中处理字符编码

在框架中使用过滤器:

  1. 创建自定义过滤器类
  2. 注册Filter过滤器对象

例子:

// 自定义过滤器
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("执行了MyFilter,doFilter ");filterChain.doFilter(servletRequest,servletResponse);}
}

注册Filter

@Configuration
public class WebApplicationConfig {@Beanpublic FilterRegistrationBean filterRegistrationBean(){FilterRegistrationBean bean  = new FilterRegistrationBean();bean.setFilter( new MyFilter());bean.addUrlPatterns("/user/*");return bean;}
}

字符集过滤器

CharacterEncodingFilter : 解决post请求中乱码的问题

在SpringMVC框架, 在web.xml 注册过滤器。 配置他的属性。

第一种方式:

使用步骤:

  1. 配置字符集过滤器

    @Configuration
    public class WebSystemConfig {//注册Servlet@Beanpublic ServletRegistrationBean servletRegistrationBean(){MyServlet myServlet = new MyServlet();ServletRegistrationBean reg = new ServletRegistrationBean(myServlet,"/myservlet");return reg;}//注册Filter@Beanpublic FilterRegistrationBean filterRegistrationBean(){FilterRegistrationBean reg = new FilterRegistrationBean();//使用框架中的过滤器类CharacterEncodingFilter filter  = new CharacterEncodingFilter();//指定使用的编码方式filter.setEncoding("utf-8");//指定request , response都使用encoding的值filter.setForceEncoding(true);reg.setFilter(filter);//指定 过滤的url地址reg.addUrlPatterns("/*");return reg;}
    }
    
  2. 修改application.properties文件, 让自定义的过滤器起作用

#SpringBoot中默认已经配置了CharacterEncodingFilter。 编码默认ISO-8859-1
#设置enabled=false 作用是关闭系统中配置好的过滤器, 使用自定义的CharacterEncodingFilter
server.servlet.encoding.enabled=false

第二种方式

修改application.properties文件

server.port=9001
server.servlet.context-path=/myboot#让系统的CharacterEncdoingFilter生效
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=utf-8
#强制request,response都使用charset属性的值
server.servlet.encoding.force=true

WEB开发应用-视图解析Thymeleaf

thymeleaf介绍

前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

jsp支持非常强大的功能,包括能写Java代码,但是呢,我们现在的这种情况,SpringBoot这个项目首先是以jar的方式,不是war,像第二,我们用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的。

那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢?

SpringBoot推荐你可以来使用模板引擎:

模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的

Thymeleaf: 是使用java开发的模板技术, 在服务器端运行。 把处理后的数据发送给浏览器。

​ 模板是作视图层工作的。 显示数据的。 Thymeleaf是基于Html语言。 Thymleaf语法是应用在

​ html标签中 。 SpringBoot框架集成Thymealeaf, 使用Thymeleaf代替jsp。

Thymeleaf is a modern server-side Java template engine for both web and standalone environments.

Thymeleaf’s main goal is to bring elegant natural templates to your development workflow — HTML that can be correctly displayed in browsers and also work as static prototypes, allowing for stronger collaboration in development teams.

With modules for Spring Framework, a host of integrations with your favourite tools, and the ability to plug in your own functionality, Thymeleaf is ideal for modern-day HTML5 JVM web development — although there is much more it can do.——Link

Thymeleaf官方文档

thymeleaf使用

引入Starter

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

自动配置好了thymeleaf

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration {...
}

自动配好的策略

  1. 所有thymeleaf的配置值都在 ThymeleafProperties

  2. 配置好了 SpringTemplateEngine

  3. 配好了 ThymeleafViewResolver

  4. 我们只需要直接开发页面

public static final String DEFAULT_PREFIX = "classpath:/templates/";//模板放置处
public static final String DEFAULT_SUFFIX = ".html";//文件的后缀名

编写一个控制层:

@Controller
public class ViewTestController {@GetMapping("/hello")public String hello(Model model){//model中的数据会被放在请求域中 request.setAttribute("a",aa)model.addAttribute("msg","一定要大力发展工业文化");model.addAttribute("link","http://www.baidu.com");return "success";}
}

/templates/success.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1 th:text="${msg}">nice</h1>
<h2><a href="www.baidu.com" th:href="${link}">去百度</a>  <br/><a href="www.google.com" th:href="@{/link}">去百度</a>
</h2>
</body>
</html>

server:servlet:context-path: /app #设置应用名

这个设置后,URL要插入/app, 如http://localhost:8080/app/hello.html

基本语法

表达式

表达式名字 语法 用途
变量取值 ${…} 获取请求域、session域、对象等值
选择变量 *{…} 获取上下文对象值
消息 #{…} 获取国际化等值
链接 @{…} 生成链接
片段表达式 ~{…} jsp:include 作用,引入公共页面片段
  1. 标准变量表达式

    语法: ${key}

    作用: 获取key对于的文本数据, key 是request作用域中的key , 使用request.setAttribute(), model.addAttribute()

    在页面中的 html标签中, 使用 th:text=“${key}”

<div style="margin-left: 400px"><h3>标准变量表达式:  ${key}</h3><p th:text="${site}">key不存在</p><br/><p>获取SysUser对象 属性值</p><p th:text="${myuser.id}">id</p><p th:text="${myuser.name}">姓名</p><p th:text="${myuser.sex}">姓名:m男</p><p th:text="${myuser.age}">年龄</p><p th:text="${myuser.getName()}">获取姓名使用getXXX</p>
</div>
  1. 选择变量表达式( 星号变量表达式)

    语法: *{key}

    作用: 获取这个key对应的数据, *{key}需要和th:object 这个属性一起使用。

    目的是简单获取对象的属性值。

    <p>使用 *{} 获取SysUser的属性值</p>
    <div th:object="${myuser}"><p th:text="*{id}"></p><p th:text="*{name}"></p><p th:text="*{sex}"></p><p th:text="*{age}"></p></div>
    <p>使用*{}完成的表示 对象的属性值</p>
    <p th:text="*{myuser.name}" ></p>
    
  2. 链接表达式

    语法: @{url}

    作用: 表示链接, 可以

     <script src="..."> , <link href="..."> <a href=".."> ,<form action="..."> <img src="...">
    

Thymeleaf属性

属性是放在html元素中的,就是html元素的属性,加入了th前缀。 属性的作用不变。 加入上th, 属性的值由模板引擎处理了。 在属性可以使用变量表达式

例如:

<form action="/loginServlet" method="post"></form><form th:action="/loginServlet" th:method="${methodAttr}"></form>

字面量

  • 文本值: ‘one text’ , ‘Another one!’ ,…
  • 数字: 0 , 34 , 3.0 , 12.3 ,…
  • 布尔值: true , false
  • 空值: null
  • 变量: one,two,… 变量不能有空格

例子:

 <div style="margin-left: 400px"><h3>文本字面量: 使用单引号括起来的字符串</h3><p th:text="'我是'+${name}+',我所在的城市'+${city}">数据显示</p><h3>数字字面量</h3><p th:if="${20>5}"> 20大于 5</p><h3>boolean字面量</h3><p th:if="${isLogin == true}">用户已经登录系统</p><h3>null字面量</h3><p th:if="${myuser != null}">有myuser数据</p></div>

文本操作

  • 字符串拼接: +
  • 变量替换: |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)

例子:

<div style="margin-left: 400px"><h3>使用运算符</h3><p th:text="${age > 10}">年龄大于 10 </p><p th:text="${ 20 + 30 }">显示运算结果</p><p th:if="${myuser == null}">myuser是null</p><p th:if="${myuser eq null}">myuser是null</p><p th:if="${myuser ne null}">myuser不是null</p><p th:text="${isLogin == true ? '用户已经登录' : '用户需要登录'}"></p><p th:text="${isLogin == true ? ( age > 10 ? '用户是大于10的' : '用户年龄比较小') : '用户需要登录'}"></p></div>三元运算符:表达式  ? true的结果 : false的结果三元运算符可以嵌套

特殊操作-设计属性值

属性是放在html元素中的,就是html元素的属性,加入了th前缀。 属性的作用不变。 加入上th, 属性的值由模板引擎处理了。 在属性可以使用变量表达式

each

each循环, 可以循环List,Array

语法:

在一个html标签中,使用th:each

<div th:each="集合循环成员,循环的状态变量:${key}"><p th:text="${集合循环成员}" ></p>
</div>集合循环成员,循环的状态变量:两个名称都是自定义的。 “循环的状态变量”这个名称可以不定义,默认是"集合循环成员Stat"

each循环Map

在一个html标签中,使用th:each

<div th:each="集合循环成员,循环的状态变量:${key}"><p th:text="${集合循环成员.key}" ></p><p th:text="${集合循环成员.value}" ></p>
</div>集合循环成员,循环的状态变量:两个名称都是自定义的。 “循环的状态变量”这个名称可以不定义,默认是"集合循环成员Stat"key:map集合中的key
value:map集合key对应的value值

th:if

“th:if” : 判断语句, 当条件为true, 显示html标签体内, 反之不显示 没有else语句

语法:
<div th:if=" 10 > 0 "> 显示文本内容 </div>

还有一个 th:unless 和 th:if相反的行为

语法:
<div th:unless=" 10 < 0 "> 当条件为false显示标签体内容 </div>

例子:if

<div style="margin-left: 400px"><h3> if 使用</h3><p th:if="${sex=='m'}">性别是男</p><p th:if="${isLogin}">已经登录系统</p><p th:if="${age > 20}">年龄大于20</p><!--""空字符是true--><p th:if="${name}">name是“”</p><!--null是false--><p th:if="${isOld}"> isOld是null</p></div>

例子: unless

 <div style="margin-left: 400px"><h3>unless: 判断条件为false,显示标签体内容</h3><p th:unless="${sex=='f'}">性别是男的</p><p th:unless="${isLogin}">登录系统</p><p th:unless="${isOld}"> isOld是null </p></div>

th:switch

th:switch 和 java中的swith一样的

语法:
<div th:switch="要比对的值"><p th:case="值1">结果1</p><p th:case="值2">结果2</p><p th:case="*">默认结果</p>以上的case只有一个语句执行</div>

th:inline

  1. 内联text: 在html标签外,获取表达式的值

    语法:

    <p>显示姓名是:[[${key}]]</p><div style="margin-left: 400px"><h3>内联 text, 使用内联表达式显示变量的值</h3><div th:inline="text"><p>我是[[${name}]],年龄是[[${age}]]</p>我是<span th:text="${name}"></span>,年龄是<span th:text="${age}"></span></div><div><p>使用内联text</p><p>我是[[${name}]],性别是[[${sex}]]</p></div>
    </div>
    
  2. 内联javascript

例子:<script type="text/javascript" th:inline="javascript">var myname = [[${name}]];var myage = [[${age}]];//alert("获取的模板中数据 "+ myname + ","+myage)function fun(){alert("单击事件,获取数据 "+ myname + ","+ [[${sex}]])}</script>

设置属性值-th:attr

  • 设置单个值
<form action="subscribe.html" th:attr="action=@{/subscribe}"><fieldset><input type="text" name="email" /><input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/></fieldset>
</form>
  • 设置多个值
<img src="../../images/gtvglogo.png"  th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

官方文档 - 5 Setting Attribute Values

迭代

<tr th:each="prod : ${prods}"><td th:text="${prod.name}">Onions</td><td th:text="${prod.price}">2.41</td><td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'"><td th:text="${prod.name}">Onions</td><td th:text="${prod.price}">2.41</td><td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>

条件运算

<a href="comments.html"th:href="@{/product/comments(prodId=${prod.id})}"th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}"><p th:case="'admin'">User is an administrator</p><p th:case="#{roles.manager}">User is a manager</p><p th:case="*">User is some other thing</p>
</div>

属性优先级

Order Feature Attributes
1 Fragment inclusion th:insert th:replace
2 Fragment iteration th:each
3 Conditional evaluation th:if th:unless th:switch th:case
4 Local variable definition th:object th:with
5 General attribute modification th:attr th:attrprepend th:attrappend
6 Specific attribute modification th:value th:href th:src ...
7 Text (tag body modification) th:text th:utext
8 Fragment specification th:fragment
9 Fragment removal th:remove

官方文档 - 10 Attribute Precedence

内置对象

文档地址:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#web-context-namespaces-for-requestsession-attributes-etc.

#request 表示 HttpServletRequest

#session 表示 HttpSession对象

session 表示Map对象的, 是#session的简单表示方式, 用来获取session中指定的key的值

​ #session.getAttribute(“loginname”) == session.loginname

这些是内置对象,可以在模板文件中直接使用。

例子:<div style="margin-left: 350px"><h3>内置对象#request,#session,session的使用</h3><p>获取作用域中的数据</p><p th:text="${#request.getAttribute('requestData')}"></p><p th:text="${#session.getAttribute('sessionData')}"></p><p th:text="${session.loginname}"></p><br/><br/><h3>使用内置对象的方法</h3>getRequestURL=<span th:text="${#request.getRequestURL()}"></span><br/>getRequestURI=<span th:text="${#request.getRequestURI()}"></span><br/>getQueryString=<span th:text="${#request.getQueryString()}"></span><br/>getContextPath=<span th:text="${#request.getContextPath()}"></span><br/>getServerName=<span th:text="${#request.getServerName()}"></span><br/>getServerPort=<span th:text="${#request.getServerPort()}"></span><br/>
</div>

内置工具类

内置工具类型: Thymeleaf自己的一些类,提供对string, date ,集合的一些处理方法

#dates: 处理日器的工具类

#numbers:处理数字的

#lists: 处理list集合的

<div style="margin-left: 350px"><h3>日期类对象 #dates</h3><p th:text="${#dates.format(mydate )}"></p><p th:text="${#dates.format(mydate,'yyyy-MM-dd')}"></p><p th:text="${#dates.format(mydate,'yyyy-MM-dd HH:mm:ss')}"></p><p th:text="${#dates.year(mydate)}"></p><p th:text="${#dates.month(mydate)}"></p><p th:text="${#dates.monthName(mydate)}"></p><p th:text="${#dates.createNow()}"></p><br/><h3>内置工具类#numbers,操作数字的</h3><p th:text="${#numbers.formatCurrency(mynum)}"></p><p th:text="${#numbers.formatDecimal(mynum,5,2)}"></p><br/><h3>内置工具类#strings,操作字符串</h3><p th:text="${#strings.toUpperCase(mystr)}"></p><p th:text="${#strings.indexOf(mystr,'power')}"></p><p th:text="${#strings.substring(mystr,2,5)}"></p><p th:text="${#strings.substring(mystr,2)}"></p><p th:text="${#strings.concat(mystr,'---java开发的黄埔军校---')}"></p><p th:text="${#strings.length(mystr)}"></p><p th:text="${#strings.length('hello')}"></p><p th:unless="${#strings.isEmpty(mystr)}"> mystring 不是 空字符串  </p><br/><h3>内置工具类#lists,操作list集合</h3><p th:text="${#lists.size(mylist)}"></p><p th:if="${#lists.contains(mylist,'a')}">有成员a</p><p th:if="!${#lists.isEmpty(mylist)}"> list 集合有多个成员</p><br/><h3>处理null</h3><p th:text="${zoo?.dog?.name}"></p></div>

自定义模板

模板是内容复用, 定义一次,在其他的模板文件中多次使用。

模板使用:

1.定义模板

2.使用模板

模板定义语法:

th:fragment="模板自定义名称"例如:
<div th:fragment="head"><p>动力节点-java开发</p><p>www.bjpowernode.com</p>
</div>

引用模板语法:

1) ~{templatename :: selector}templatename:  文件名称selector: 自定义模板名称
2)templatename :: selectortemplatename:  文件名称selector: 自定义模板名称对于使用模板:有包含模板(th:include), 插入模板(th:insert)

开发场景—数据访问

导入JDBC场景

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

接着导入数据库驱动包(MySQL为例)。

<!--默认版本:-->
<mysql.version>8.0.22</mysql.version><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><!--<version>5.1.49</version>-->
</dependency><!--
想要修改版本
1、直接依赖引入具体版本(maven的就近依赖原则)
2、重新声明版本(maven的属性的就近优先原则)
-->
<properties><java.version>1.8</java.version><mysql.version>5.1.49</mysql.version>
</properties>

相关数据源配置类

  • DataSourceAutoConfiguration : 数据源的自动配置。

    • 修改数据源相关的配置:spring.datasource
    • 数据库连接池的配置,是自己容器中没有DataSource才自动配置的
    • 底层配置好的连接池是:HikariDataSource
  • DataSourceTransactionManagerAutoConfiguration: 事务管理器的自动配置。

  • JdbcTemplateAutoConfigurationJdbcTemplate的自动配置,可以来对数据库进行CRUD。

    • 可以修改前缀为spring.jdbc的配置项来修改JdbcTemplate
    • @Bean @Primary JdbcTemplate:Spring容器中有这个JdbcTemplate组件,使用@Autowired
  • JndiDataSourceAutoConfiguration: JNDI的自动配置。

  • XADataSourceAutoConfiguration: 分布式事务相关的。

修改配置项

spring:datasource:url: jdbc:mysql://localhost:3306/db_accountusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driver

​ 这里其实要提出一个问题的,目前的数据源配置格式是一个通用格式,不管你换什么数据源都可以用这种形式进行配置。但是新的问题又来了,如果对数据源进行个性化的配置,例如配置数据源对应的连接数量,这个时候就有新的问题了。每个数据源技术对应的配置名称都一样吗?肯定不是啊,各个厂商不可能提前商量好都写一样的名字啊,怎么办?就要使用专用的配置格式了。这个时候上面这种通用格式就不能使用了,怎么办?还能怎么办?按照SpringBoot整合其他技术的通用规则来套啊,导入对应的starter,进行相应的配置即可。

数据访问-自定义方式整合druid数据源

Druid官网

Druid是什么?

它是数据库连接池,它能够提供强大的监控和扩展功能。

官方文档 - Druid连接池介绍

Spring Boot整合第三方技术的两种方式:

  • 自定义

  • 找starter场景

自定义方式

添加依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.17</version>
</dependency>

配置Druid数据源

@Configuration
public class MyConfig {@Bean@ConfigurationProperties("spring.datasource")//复用配置文件的数据源配置public DataSource dataSource() throws SQLException {DruidDataSource druidDataSource = new DruidDataSource();//        druidDataSource.setUrl();
//        druidDataSource.setUsername();
//        druidDataSource.setPassword();return druidDataSource;}
}

更多配置项

配置Druid的监控页功能

  • Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。官方文档 - 配置_StatViewServlet配置。这个StatViewServlet的用途包括:

    • 提供监控信息展示的html页面
    • 提供监控信息的JSON API
  • Druid内置提供一个StatFilter,用于统计监控信息。官方文档 - 配置_StatFilter

  • WebStatFilter用于采集web-jdbc关联监控的数据,如SQL监控、URI监控。官方文档 - 配置_配置WebStatFilter

  • Druid提供了WallFilter,它是基于SQL语义分析来实现防御SQL注入攻击的。官方文档 - 配置 wallfilter

@Configuration
public class MyConfig {@Bean@ConfigurationProperties("spring.datasource")public DataSource dataSource() throws SQLException {DruidDataSource druidDataSource = new DruidDataSource();//加入监控和防火墙功能功能druidDataSource.setFilters("stat,wall");return druidDataSource;}/*** 配置 druid的监控页功能* @return*/@Beanpublic ServletRegistrationBean statViewServlet(){StatViewServlet statViewServlet = new StatViewServlet();ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");//监控页账号密码:registrationBean.addInitParameter("loginUsername","admin");registrationBean.addInitParameter("loginPassword","123456");return registrationBean;}/*** WebStatFilter 用于采集web-jdbc关联监控的数据。*/@Beanpublic FilterRegistrationBean webStatFilter(){WebStatFilter webStatFilter = new WebStatFilter();FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(webStatFilter);filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");return filterRegistrationBean;}}

数据访问-druid数据源starter整合方式

官方文档 - Druid Spring Boot Starter

引入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.17</version>
</dependency>

分析自动配置

  • 扩展配置项 spring.datasource.druid
  • 自动配置类DruidDataSourceAutoConfigure
  • DruidSpringAopConfiguration.class, 监控SpringBean的;配置项:spring.datasource.druid.aop-patterns
  • DruidStatViewServletConfiguration.class, 监控页的配置。spring.datasource.druid.stat-view-servlet默认开启。
  • DruidWebStatFilterConfiguration.class,web监控配置。spring.datasource.druid.web-stat-filter默认开启。
  • DruidFilterConfiguration.class所有Druid的filter的配置:
private static final String FILTER_STAT_PREFIX = "spring.datasource.druid.filter.stat";
private static final String FILTER_CONFIG_PREFIX = "spring.datasource.druid.filter.config";
private static final String FILTER_ENCODING_PREFIX = "spring.datasource.druid.filter.encoding";
private static final String FILTER_SLF4J_PREFIX = "spring.datasource.druid.filter.slf4j";
private static final String FILTER_LOG4J_PREFIX = "spring.datasource.druid.filter.log4j";
private static final String FILTER_LOG4J2_PREFIX = "spring.datasource.druid.filter.log4j2";
private static final String FILTER_COMMONS_LOG_PREFIX = "spring.datasource.druid.filter.commons-log";
private static final String FILTER_WALL_PREFIX = "spring.datasource.druid.filter.wall";

配置示例

spring:datasource:url: jdbc:mysql://localhost:3306/db_accountusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverdruid:aop-patterns: com.atguigu.admin.*  #监控SpringBeanfilters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)stat-view-servlet:   # 配置监控页功能enabled: truelogin-username: adminlogin-password: adminresetEnable: falseweb-stat-filter:  # 监控webenabled: trueurlPattern: /*exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'filter:stat:    # 对上面filters里面的stat的详细配置slow-sql-millis: 1000logSlowSql: trueenabled: truewall:enabled: trueconfig:drop-table-allow: false

总结

  1. 整合Druid需要导入Druid对应的starter
  2. 根据Druid提供的配置方式进行配置
  3. 整合第三方技术通用方式
    • 导入对应的starter
    • 根据提供的配置格式,配置非默认值对应的配置项

数据访问-整合MyBatis-配置版

MyBatis的GitHub仓库

MyBatis官方

使用MyBatis框架操作数据, 在SpringBoot框架集成MyBatis

使用步骤:

  1. mybatis起步依赖 : 完成mybatis对象自动配置, 对象放在容器中

  2. pom.xml 指定把src/main/java目录中的xml文件包含到classpath中

  3. 创建实体类Student

  4. 创建Dao接口 StudentDao , 创建一个查询学生的方法

  5. 创建Dao接口对应的Mapper文件, xml文件, 写sql语句

  6. 创建Service层对象, 创建StudentService接口和他的实现类。 去dao对象的方法。完成数据库的操作

  7. 创建Controller对象,访问Service。

  8. 写application.properties文件

    配置数据库的连接信息。

第一种方式 : @Mapper

@Mapper:放在dao接口的上面, 每个接口都需要使用这个注解。

/*** @Mapper:告诉MyBatis这是dao接口,创建此接口的代理对象。*     位置:在类的上面*/
@Mapper
public interface StudentDao {Student selectById(@Param("stuId") Integer id);
}

第二种方式 : @MapperScan

/*** @MapperScan: 找到Dao接口和Mapper文件*     basePackages:Dao接口所在的包名*/
@SpringBootApplication
@MapperScan(basePackages = {"com.bjpowernode.dao","com.bjpowernode.mapper"})
public class Application {}

第三种方式: Mapper文件和Dao接口分开管理

现在把Mapper文件放在resources目录下

1)在resources目录中创建子目录 (自定义的) , 例如mapper

2)把mapper文件放到 mapper目录中

3)在application.properties文件中,指定mapper文件的目录

#指定mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定mybatis的日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
  1. 在pom.xml中指定 把resources目录中的文件 , 编译到目标目录中
<!--resources插件-->
<resources><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource>
</resources>

事务

Spring框架中的事务:

1) 管理事务的对象: 事务管理器(接口, 接口有很多的实现类)

​ 例如:使用Jdbc或mybatis访问数据库,使用的事务管理器:DataSourceTransactionManager

2 ) 声明式事务: 在xml配置文件或者使用注解说明事务控制的内容

​ 控制事务: 隔离级别,传播行为, 超时时间

3)事务处理方式:

​ 1) Spring框架中的@Transactional

​ 2) aspectj框架可以在xml配置文件中,声明事务控制的内容

SpringBoot中使用事务: 上面的两种方式都可以。

1)在业务方法的上面加入@Transactional , 加入注解后,方法有事务功能了。

2)明确的在 主启动类的上面 ,加入@EnableTransactionManager

例子:

/*** @Transactional: 表示方法的有事务支持*       默认:使用库的隔离级别, REQUIRED 传播行为; 超时时间  -1*       抛出运行时异常,回滚事务*/
@Transactional
@Override
public int addStudent(Student student) {System.out.println("业务方法addStudent");int rows  =  studentDao.insert(student);System.out.println("执行sql语句");//抛出一个运行时异常, 目的是回滚事务//int m   = 10 / 0 ;return rows;
}

starter的命名方式

  1. SpringBoot官方的Starter:spring-boot-starter-*
  2. 第三方的: *-spring-boot-starter

引入依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version>
</dependency>

配置模式:

  • 全局配置文件

  • SqlSessionFactory:自动配置好了

  • SqlSession:自动配置了SqlSessionTemplate 组合了SqlSession

  • @Import(AutoConfiguredMapperScannerRegistrar.class)

  • Mapper: 只要我们写的操作MyBatis的接口标准了@Mapper就会被自动扫描进来

@EnableConfigurationProperties(MybatisProperties.class) : MyBatis配置项绑定类。
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration{...
}@ConfigurationProperties(prefix = "mybatis")
public class MybatisProperties{...
}

配置文件

spring:datasource:username: rootpassword: 1234url: jdbc:mysql://localhost:3306/mydriver-class-name: com.mysql.jdbc.Driver# 配置mybatis规则
mybatis:config-location: classpath:mybatis/mybatis-config.xml  #全局配置文件位置mapper-locations: classpath:mybatis/*.xml  #sql映射文件位置

mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 由于Spring Boot自动配置缘故,此处不必配置,只用来做做样。-->
</configuration>

Mapper接口

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lun.boot.mapper.UserMapper"><select id="getUser" resultType="com.lun.boot.bean.User">select * from user where id=#{id}</select>
</mapper>
import com.lun.boot.bean.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper {public User getUser(Integer id);
}

POJO

public class User {private Integer id;private String name;//getters and setters...
}

DB

CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(45) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

Controller and Service

@Controller
public class UserController {@Autowiredprivate UserService userService;@ResponseBody@GetMapping("/user/{id}")public User getUser(@PathVariable("id") Integer id){return userService.getUser(id);}}
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;//IDEA下标红线,可忽视这红线public User getUser(Integer id){return userMapper.getUser(id);}}

配置private Configuration configuration; 也就是配置mybatis.configuration相关的,就是相当于改mybatis全局配置文件中的值。(也就是说配置了mybatis.configuration,就不需配置mybatis全局配置文件了)

# 配置mybatis规则
mybatis:mapper-locations: classpath:mybatis/mapper/*.xml# 可以不写全局配置文件,所有全局配置文件的配置都放在configuration配置项中了。# config-location: classpath:mybatis/mybatis-config.xmlconfiguration:map-underscore-to-camel-case: true

小结

  • 导入MyBatis官方Starter。
  • 编写Mapper接口,需@Mapper注解。
  • 编写SQL映射文件并绑定Mapper接口。
  • application.yaml中指定Mapper配置文件的所处位置,以及指定全局配置文件的信息 (建议:配置在mybatis.configuration)。

数据访问-整合MyBatis-注解配置混合版

你可以通过Spring Initializr添加MyBatis的Starer。

注解与配置混合搭配,干活不累

@Mapper
public interface UserMapper {public User getUser(Integer id);@Select("select * from user where id=#{id}")public User getUser2(Integer id);public void saveUser(User user);@Insert("insert into user(`name`) values(#{name})")@Options(useGeneratedKeys = true, keyProperty = "id")public void saveUser2(User user);}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lun.boot.mapper.UserMapper"><select id="getUser" resultType="com.lun.boot.bean.User">select * from user where id=#{id}</select><insert id="saveUser" useGeneratedKeys="true" keyProperty="id">insert into user(`name`) values(#{name})</insert></mapper>
  • 简单DAO方法就写在注解上。复杂的就写在配置文件里。

  • 使用@MapperScan("com.lun.boot.mapper") 简化,Mapper接口就可以不用标注@Mapper注解。

@MapperScan("com.lun.boot.mapper")
@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}}

数据访问-整合MyBatisPlus操作数据库

IDEA的MyBatis的插件 - MyBatisX

MyBatisPlus官网

MyBatisPlus官方文档

MyBatisPlus是什么

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。


添加依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version>
</dependency>
  • MybatisPlusAutoConfiguration配置类,MybatisPlusProperties配置项绑定。

  • SqlSessionFactory自动配置好,底层是容器中默认的数据源。

  • mapperLocations自动配置好的,有默认值classpath*:/mapper/**/*.xml,这表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件放在 mapper下。

  • 容器中也自动配置好了SqlSessionTemplate

  • @Mapper 标注的接口也会被自动扫描,建议直接 @MapperScan("com.lun.boot.mapper")批量扫描。

  • MyBatisPlus优点之一:只需要我们的Mapper继承MyBatisPlus的BaseMapper 就可以拥有CRUD能力,减轻开发工作。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lun.hellomybatisplus.model.User;public interface UserMapper extends BaseMapper<User> {}

​ 而MyBatis与MyBatisPlus这两个坐标的名字书写比较特殊,是第三方技术名称在前,boot和starter在后。此处简单提一下命名规范,后期原理篇会再详细讲解

starter所属 命名规则 示例
官方提供 spring-boot-starter-技术名称 spring-boot-starter-web
spring-boot-starter-test
第三方提供 第三方技术名称-spring-boot-starter mybatis-spring-boot-starter
druid-spring-boot-starter
第三方提供 第三方技术名称-boot-starter(第三方技术名称过长,简化命名) mybatis-plus-boot-starter

温馨提示

​ 有些小伙伴在创建项目时想通过勾选的形式找到这个名字,别翻了,没有。截止目前,SpringBoot官网还未收录此坐标,而我们Idea创建模块时读取的是SpringBoot官网的Spring Initializr,所以也没有。如果换用阿里云的url创建项目可以找到对应的坐标。

总结

技术总结

创建对象的:
@Controller: 放在类的上面,创建控制器对象,注入到容器中
@RestController: 放在类的上面,创建控制器对象,注入到容器中。作用:复合注解是@Controller , @ResponseBody, 使用这个注解类的,里面的控制器方法的返回值                   都是数据@Service : 放在业务层的实现类上面,创建service对象,注入到容器
@Repository : 放在dao层的实现类上面,创建dao对象,放入到容器。 没有使用这个注解,是因为现在使用MyBatis框               架,  dao对象是MyBatis通过代理生成的。 不需要使用@Repository、 所以没有使用。
@Component:  放在类的上面,创建此类的对象,放入到容器中。 赋值的:
@Value : 简单类型的赋值, 例如 在属性的上面使用@Value("李四") private String name还可以使用@Value,获取配置文件者的数据(properties或yml)。 @Value("${server.port}") private Integer port@Autowired: 引用类型赋值自动注入的,支持byName, byType. 默认是byType 。 放在属性的上面,也可以放在构造             方法的上面。 推荐是放在构造方法的上面
@Qualifer:  给引用类型赋值,使用byName方式。   @Autowird, @Qualifer都是Spring框架提供的。@Resource : 来自jdk中的定义, javax.annotation。 实现引用类型的自动注入, 支持byName, byType.默认是byName, 如果byName失败, 再使用byType注入。 在属性上面使用其他:
@Configuration : 放在类的上面,表示这是个配置类,相当于xml配置文件@Bean:放在方法的上面, 把方法的返回值对象,注入到spring容器中。@ImportResource : 加载其他的xml配置文件, 把文件中的对象注入到spring容器中@PropertySource : 读取其他的properties属性配置文件@ComponentScan: 扫描器 ,指定包名,扫描注解的@ResponseBody: 放在方法的上面,表示方法的返回值是数据, 不是视图
@RequestBody : 把请求体中的数据,读取出来, 转为java对象使用。@ControllerAdvice:  控制器增强, 放在类的上面, 表示此类提供了方法,可以对controller增强功能。@ExceptionHandler : 处理异常的,放在方法的上面@Transcational :  处理事务的, 放在service实现类的public方法上面, 表示此方法有事务SpringBoot中使用的注解@SpringBootApplication : 放在启动类上面, 包含了@SpringBootConfiguration@EnableAutoConfiguration, @ComponentScanMyBatis相关的注解@Mapper : 放在类的上面 , 让MyBatis找到接口, 创建他的代理对象
@MapperScan :放在主类的上面 , 指定扫描的包, 把这个包中的所有接口都创建代理对象。 对象注入到容器中
@Param : 放在dao接口的方法的形参前面, 作为命名参数使用的。

结语

​ 基础篇到这里就全部结束了,在基础篇中学习了如何创建一个SpringBoot工程,然后学习了SpringBoot的基础配置语法格式,接下来对常见的市面上的实用技术做了整合,整体来说就是一个最基本的入门,关于SpringBoot的实际开发其实接触的还是很少的,之后会推出下篇,各位小伙伴,加油学习,再见。

Spring Boot 教学 学习 讲义笔记 【入门到精通一篇就够了】(上)相关推荐

  1. 小程序入门到精通一篇就够了!

    一.小程序介绍 1.1.小程序是什么 官方文档:微信开放文档 微信小程序,简称小程序,英文名 MiniProgram ,是一种不需要下载安装即可使用的应用,它实现了应用 " 触手可及 &qu ...

  2. Spring Boot 2 学习笔记(2 / 2)

    Spring Boot 2 学习笔记(1 / 2) - - - 45.web实验-抽取公共页面 46.web实验-遍历数据与页面bug修改 47.视图解析-[源码分析]-视图解析器与视图 48.拦截器 ...

  3. Spring Boot 框架学习笔记(五)( SpringSecurity安全框架 )

    Spring Boot 框架学习笔记(五) SpringSecurity安全框架 概述 作用 开发示例: 1. 新建项目 2. 引入依赖 3. 编写`SecurityConfig`类,实现认证,授权, ...

  4. Spring Boot 框架学习笔记(二)(配置文件与数据注入 yaml基本语法 JSR303数据验证 多环境切换 )

    Spring Boot 框架学习笔记(二) 六.appliaction.properties配置与数据注入 6.1 `@Value`注解 测试注入数据 读取输入流 6.2 读取配置文件数据注入 单文件 ...

  5. Spring boot 全面学习笔记(1)

    JAVAEE 回顾 Java EE 是一种企业应用的软件架构. Java EE 与Web : 互联网从根本上改变了对企业软件的系统需求,软件需要处理来自互联网的大量请求, 并要及时做出响应. Java ...

  6. Spring Boot的学习之路(02):和你一起阅读Spring Boot官网

    官网是我们学习的第一手资料,我们不能忽视它.却往往因为是英文版的,我们选择了逃避它,打开了又关闭. 我们平常开发学习中,很少去官网上看.也许学完以后,我们连官网长什么样子,都不是很清楚.所以,我们在开 ...

  7. spring boot框架学习2-spring boot核心(1)

    本节主要: 1:解析spring boot入口和@SpringBootApplication源码详解 SpringBootApplication包含: @SpringBootConfiguration ...

  8. Spring Boot的学习之路(03):基础环境搭建,做好学习前的准备工作

    1. 前言 <论语·魏灵公>:"工欲善其事,必先利其器.居是邦也,事其大夫之贤者,友其士之仁者." 工欲善其事必先利其器.我们在熟悉一个陌生项目的时候,首先会大概去看一 ...

  9. spring boot框架学习学前掌握之重要注解(2)-通过java的配置方式进行配置spring

    本节主要内容: 1:通过代码演示实现零XML配置spring 2:使用重点注解理解 声明: 本文是<凯哥陪你学系列-框架学习之spring boot框架学习>中spring boot框架学 ...

最新文章

  1. 腾讯云 短信服务 【学习记录 】
  2. andorid 全部对话框
  3. 因特网使用期限_Internet死亡时使用PC的其他方式
  4. android 编辑9图片,Android基础入门教程——1.6 .9(九妹)图片怎么玩
  5. ionic2 安装与cordova打包
  6. [转]基于图的机器学习技术:谷歌众多产品和服务背后的智能
  7. python api测试框架_python api 测试框架
  8. Android 命名规范 (提高代码可以读性) 转
  9. bitlocker密钥输入后一直没用_win10系统bitlocker解锁后如何上锁
  10. linux查看日志内存,关于linux查询内存,CPU,存储空间和日志查询的的常用命令及参数-站长资讯中心...
  11. dategridview代码选中行_使用IntelliJ IDEA进行Java代码调试的技巧
  12. 数学也荒唐:20个脑洞大开的数学趣题
  13. 请根据以下需求使用决策表设计测试用例
  14. 多元统计分析及R语言建模(王斌会)第十、十一、十二章答案
  15. 2022-2028年中国保健食品行业市场运营格局及前景战略分析报告
  16. 神经网络与矩阵表示之间的恩怨情仇
  17. 不会PS图片怎么批量调色
  18. 2019icpc计算机程序设计大赛,常熟理工学院新闻网
  19. vue css变量实现多主题皮肤切换
  20. 基于stm32的滤波器的总结

热门文章

  1. 哈希表(C++实现)
  2. IT治理-组织体系建设
  3. java计算机毕业设计面相高校学生的图书共享平台源代码+数据库+系统+lw文档
  4. 松翰SN8P2711-C替换料
  5. 深入原理64式:16 B树,B+树与mysql索引
  6. tensorfow使用基础(3)--MNiST--1
  7. 数据结构 耿国华老师讲
  8. 如果苹果和三大运营商都合作
  9. USB虚拟串口实验_STM32F1开发指南——USB学习笔记
  10. (摘自网络)名人论上帝