SpringBoot学习笔记

1、Spring Boot简介

Spring Boot 是 Pivotal 团队在 Spring 的基础上提供的一套全新的开源框架,其目的是为了简化 Spring 应用的搭建和开发过程。Spring Boot 去除了大量的 XML 配置文件,简化了复杂的依赖管理。

Spring Boot 具有 Spring 一切优秀特性,Spring 能做的事,Spring Boot 都可以做,而且使用更加简单,功能更加丰富,性能更加稳定而健壮。随着近些年来微服务技术的流行,Spring Boot 也成了时下炙手可热的技术。

Spring Boot 集成了大量常用的第三方库配置,Spring Boot 应用中这些第三方库几乎可以是零配置的开箱即用(out-of-the-box),大部分的 Spring Boot 应用都只需要非常少量的配置代码(基于 Java 的配置),开发者能够更加专注于业务逻辑。

Spring Boot的特点
1.Spring Boo可以以jar包的形式独立运行,Spring Boot项目只需通过命令"java-jar.xx.jar"即可运行。
2.内嵌Servlet容器。Spring Boot使用了嵌入式的Servlet容器(例如Tomcat、Jettty或者Undertwo等),应用无需打成WAR包。
3.提供starter简化Maven配置。Spring Boot提供了一系列的starter项目对象模型(POMS)来简化Maven配置。
4.提供了大量的自动配置。Spring Boot提供了大量的默认自动配置,来简化项目的开发,开发人员也可以通过配置文件修改默认配置。
5.自带应用监控。Spring Boot可以对正在运行的项目提供监控。
6.无代码生成和xml配置。SpringBoot不需要任何xml配置即可实现Spring的所有配置。

2、构建一个Spring Boot的项目

使用工具Intelij IDEA。
两种构建方式:
1、使用Maven构建。
添加项目依赖

<project>
    ...
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
  
    <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>

编写主程序类(可自定义命名),用于启动SpringBoot应用。

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

2、使用Spring Initalizr创建。
IDEA下点击文件——打开——项目,在按下图操作。
在这里插入图片描述
后面的操作自定义即可。

3、Spring Boot start

starter
start是Spring Boot将日常企业应用研究中的各种场景都抽取出来,整合出来可能用到的依赖。用户只需要在Maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。

并不是所有的 starter 都是由 Spring Boot 官方提供的,也有部分 starter 是第三方技术厂商提供的,例如 druid-spring-boot-starter 和 mybatis-spring-boot-starter 等等。当然也存在个别第三方技术,Spring Boot 官方没提供 starter,第三方技术厂商也没有提供 starter。

spring-boot-starter-parent
spring-boot-starter-parent是项目的父级依赖,它被称为Spring Boot的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。

spring-boot-starter-parent
spring-boot-starter-parent 是所有 Spring Boot 项目的父级依赖,它被称为 Spring Boot 的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。

Spring Boot 项目可以通过继承 spring-boot-starter-parent 来获得一些合理的默认配置,它主要提供了以下特性:
(1)默认 JDK 版本(Java 8)
(2)默认字符集(UTF-8)
(3)依赖管理功能
(4)资源过滤
(5)默认插件配置
(6)识别 application.properties 和 application.yml 类型的配置文件

4、YAML入门

yaml语法如下

  • 使用缩进表示层级。
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 同级元素必须左侧对齐。
  • 大小写敏感。

yaml配置的写法
1.yaml字面量写法
字面量是指单个的,不可拆分的值。如:数字、字符串、布尔值、日期等。yaml的字面量语法为"key:[空格]value"的形式表示一对键值对(空格不能省略)。

2.yaml对象写法
在Yaml中,对象可能包含多个属性,每一个属性都是一对键值。
普通写法

website: 
  name: bianchengbang
  url: www.biancheng.net

行内写法

website: {name: bianchengbang,url: www.biancheng.net}

3.数组写法
yaml使用"-"表示数组中的元素

pets:
  -dog
  -cat
  -pig

4.多文档组织结构
一个yaml文件可以由一个或多个文档组成,文档之间使用"—"作为分隔符,且文档之间相互独立,互不干扰。


纯文本复制
---
website:
  name: bianchengbang
  url: www.biancheng.net
---
website: {name: bianchengbang,url: www.biancheng.net}
pets:
  -dog
  -cat
  -pig

5、多环境配置

为了便于开发我们可以配置多套SpringBoot的环境,例如我们可以将测试与开发分别配置一套环境。以下提供了使用properties与yaml的两种配置方式,两者可任选其一。但需要注意一点,如果一个项目中同时有application.properties与application.yaml配置SpringBoot默认加载的是properties文件。
使用properties文件进行多环境配置
1.编写两套环境test与dev
test测试环境

server.port=8081
···

dev开发环境

server.port=8082
···

2.在SpringBoot的默认配置文件application.properties中选择激活哪一个配置文件

# springboot的多环境配置,可以选择激活哪一个配置文件
spring.profiles.active=dev

使用yaml文件进行多环境配置
根据yaml的多文档组织结构,我们可以在一个yaml文件当中进行多个环境的配置。

# 使用yaml的多文档编辑模式,可以使用“---“将代码风格成多个文档
server:
  port: 8081
#选择当前激活哪个环境
spring:
  profiles:
    active: dev

---
server:
  port: 8082
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: test

6、配置绑定@ConfigurationProperties与@Value的用法

所谓“配置绑定”就是将配置文件中的值与JavaBean中对应的属性进行绑定。即将一些配置信息放在配置文件中,然后通过Java代码读取配置文件,将指定的配置封装到JavaBean(实体类)中。
SpringBoot提供了2中方式进行配置绑定:@ConfigurationProperties与@Value注解

1、使用@ConfigurationProperties配置绑定
第一步,在全局配置文件application.yml中添加自定义属性

person:
  lastName: 张三
  age: 18
  boss: false
  birth: 1990/12/12
  maps: { k1: v1,k2: 12 }
  lists:
    ‐ lisi
    ‐ zhaoliu
  dog:
    name: 迪迪
    age: 5

第二步,创建Person的实体类,使用@ConfigurationProperties注解将以上配置文件中的属性映射到这个实体类上。这一步要格外注意,要是使用@ConfigurationProperties注解进行配置绑定,首先就要保证该对象在IOC容器中,需要用到@Component注解来添加组件到容器中。
JavaBean上使用了注解@ConfigurationProperties(prefix=‘person’)是将当前JavaBean中以"person"为前缀的配置进行绑定。

/**
* 将配置文件中配置的每一个属性的值,映射到这个组件中
*
* @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
* prefix = "person":配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}

2、使用@Value进行配置绑定

@Component
@Data
public class Person {
    @Value("${person.lastName}")
    private String lastName;
    @Value("${person.age}")
    private Integer age;
    @Value("${person.boss}")
    private Boolean boss;
    @Value("${person.birth}")
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
}

3、@Value与@ConfigurationProperties对比

不同\注解@ConfigurationProperties@Value
位置类上属性上
功能批量绑定配置文件中的配置只能一个一个指定需要绑定的配置
是否支持松散绑定支持松散绑定,如属性lastName可以绑定配置文件名中的person.lastName,person.last-name,person.last_name,person_last_name不支持
是否支持SpEL不支持SpEL表达式支持SpEL表达式
复杂类型封装支持所有类型数据的封装,包括Map、List、及对象属性等不支持,仅支持基本数据类型

4、读取application.yaml外的配置文件
如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此我们通常会将与 Spring Boot 无关的配置(例如自定义配置)提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用 @PropertySource 注解指向该配置文件。
在这里插入图片描述
配置方法

@Data
@AllArgsConstructor
@NoArgsConstructor
@PropertySource(value = "classpath:user.properties",ignoreResourceNotFound = true,encoding = "UTF-8")
@Component
@ConfigurationProperties("u")
public class User {
    private String name;
    private Integer age;
}

注意,SpringBoot读取properties文件时,可能会出现中文乱码的问题。需要在项目中将properties文件的编码格式设置为utf-8,然后在在引入时添加属性值ignoreResourceNotFound = true,encoding = "UTF-8"即可。

7、导入Spring配置

如何将Spring配置添加到SpringBoot项目的配置当中。
1、使用@ImportResource的注解加载Spring配置文件。
例:
在项目中创建一个Person实体类

@Data
public class Person {
    private String name;
    private Integer age;
}

编写一个Spring配置文件bean.xml,注入一个person的对象。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person" class="com.example.pojo.Person">
        <property name="name" value="啊U"/>
        <property name="age" value="1"/>
    </bean>
</beans>

接下来在SpringBoot的启动类当中使用@ImportResource注解即可将这个Spring配置文件整合到SpringBoot项目当中。

@ImportResource(locations = "classpath:bean.xml")
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

可以编写以下代码测试是否成功整合了Spring的配置文件。

@RestController
public class A {

    @Autowired
    private Person person;

    @RequestMapping("/b")
    public Person person(){
        return person;
    }
}

2、使用JavaConfig的方式加载Spring配置
Spring Boot 推荐我们使用全注解的方式加载 Spring 配置,实现方式:
1、使用 @Configuration 注解定义配置类,替换 Spring 的配置文件;
2、配置类内部可以包含有一个或多个被 @Bean 注解的方法,这些方法会被 AnnotationConfigApplicationContext 或 AnnotationConfigWebApplicationContext 类扫描,构建 bean 定义(相当于 Spring 配置文件中的标签),方法的返回值会以组件的形式添加到容器中,组件的 id 就是方法名。

@Configuration
public class MyConfig {
    @Bean
    public Person m(){
        return new Person("aa",1);
    }
}

8、默认全局配置文件

SpringBoot项目默认使用以下2种类型的全局配置文件application.properties或application.yml,其文件名是固定的。在项目中可以同时存在多个 application.properties 或 apllication.yml,Spring Boot 启动时会扫描以下 5 个位置的 application.properties 或 apllication.yml 文件,并将它们作为 Spring boot 的默认配置文件。

  • file:./config/
  • file:./config/*/
  • file:./
  • classpath:/config/
  • classpath:/

注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。

以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。

所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:
存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;
存在不同的配置内容时,高优先级和低优先级的配置内容取并集。

9、外部配置文件

除了默认配置文件,Spring Boot 还可以加载一些位于项目外部的配置文件。我们可以通过如下 2 个参数,指定外部配置文件的路径:
spring.config.location
spring.config.additional-location

spring.config.location
我们可以先将 Spring Boot 项目打包成 JAR 文件,然后在命令行启动命令中,使用命令行参数 --spring.config.location,指定外部配置文件的路径。
(1)项目打包
mvn clean package
(2)跳转到打包后的jar目录,运行
java -jar springbootdemo-0.0.1-SNAPSHOT.jar --spring.config.location=D:\myConfig\my-application.yml

需要注意的是,使用该参数指定配置文件后,会使项目默认配置文件(application.properties 或 application.yml )失效,Spring Boot 将只加载指定的外部配置文件。

spring.config.additional-location
同样的打包项目,在生成的jar包目录下运行:
java -jar {JAR} --spring.config.additional-location={外部配置文件全路径}

与 --spring.config.location 不同,–spring.config.additional-location 不会使项目默认的配置文件失效,使用该命令行参数添加的外部配置文件会与项目默认的配置文件共同生效,形成互补配置,且其优先级是最高的,比所有默认配置文件的优先级都高。

注意:项目打包项目打包后根目录下的配置文件会失效的解决方案
Spring Boot 项目打包后,项目根目录下的配置文件无法被加载,我们可以通过以下 3 种方式解决这个问题。
方式一:在 IDEA 的运行配置(Run/Debug Configuration)中,添加虚拟机参数 -Dspring.config.additional-location=D:\myConfig\my-application.yml,指定外部配置文件;
方式二:在 IDEA 的运行配置(Run/Debug Configuration)中,添加程序运行参数 --spring.config.additional-location=D:\myConfig\my-application.yml,指定外部配置文件;
方式三:在主启动类中调用 System.setProperty()方法添加系统属性 spring.config.additional-location,指定外部配置文件。

10、SpringBoot配置方式

Spring Boot 不仅可以通过配置文件进行配置,还可以通过环境变量、命令行参数等多种形式进行配置。

SpringBoot配置优先级
以下是常用的 Spring Boot 配置形式及其加载顺序(优先级由高到低):

  1. 命令行参数
  2. 来自 java:comp/env 的 JNDI 属性
  3. Java 系统属性(System.getProperties())
  4. 操作系统环境变量
  5. RandomValuePropertySource 配置的 random.* 属性值
  6. 配置文件(YAML 文件、Properties 文件)
  7. @Configuration 注解类上的 @PropertySource 指定的配置文件
  8. 通过 SpringApplication.setDefaultProperties 指定的默认属性

以上所有形式的配置都会被加载,相同取高,不同取并。

11、SpringBoot自动配置的原理

我们知道,Spring Boot 项目创建完成后,即使不进行任何的配置,也能够顺利地运行,这都要归功于 Spring Boot 的自动化配置。Spring Boot 默认使用 application.properties 或 application.yml 作为其全局配置文件,我们可以在该配置文件中对各种自动配置属性进行修改,并使之生效。
Spring Boot 的自动配置是基于 Spring Factories 机制实现的。Spring Factories 机制是 Spring Boot 中的一种服务发现机制,这种扩展机制与 Java SPI 机制十分相似。Spring Boot 会自动扫描所有 Jar 包类路径下 META-INF/spring.factories 文件,并读取其中的内容,进行实例化,这种机制也是 Spring Boot Starter 的基础。

12、日志配置及输出

在项目开发中,日志十分的重要,不管是记录运行情况还是定位线上问题,都离不开对日志的分析。
日志框架的选择
市面上常见的日志框架有很多,它们可以被分为两类:日志门面(日志抽象层)和日志实现,如下表。

日志分类描述举例
日志门面(日志抽象层)为 Java 日志访问提供一套标准和规范的 API 框架,其主要意义在于提供接口。JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、jboss-logging
日志实现日志门面的具体的实现Log4j、JUL(java.util.logging)、Log4j2、Logback

通常情况下,日志由一个日志门面与一个日志实现组合搭建而成,Spring Boot 选用 SLF4J + Logback 的组合来搭建日志系统。
SLF4J 是目前市面上最流行的日志门面,使用 Slf4j 可以很灵活的使用占位符进行参数占位,简化代码,拥有更好的可读性。
Logback 是 Slf4j 的原生实现框架,它与 Log4j 出自一个人之手,但拥有比 log4j 更多的优点、特性和更做强的性能,现在基本都用来代替 log4j 成为主流。
在项目开发中,记录日志时不应该直接调用日志实现层的方法,而应该调用日志门面(日志抽象层)的方法。
在使用 SLF4J 记录日志时,我们需要在应用中导入 SLF4J 及日志实现,并在记录日志时调用 SLF4J 的方法,例如:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);
       //调用 sl4j 的 info() 方法,而非调用 logback 的方法
        logger.info("Hello World");
    }
}

SpringBoot统一日志框架的选用

使用 SLF4J+Logback 记录日志
SLF4J + Logback的配置是SpringBoot的默认配置,并提供了默认配置,即使我们不进行任何额外配,也可以使用 SLF4J+Logback 进行日志输出。
依赖在此

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

常见的日志配置包括日志级别、日志的输入出格式等内容。

日志级别
日志的输出都是分级别的,当一条日志信息的级别大于或等于配置文件的级别时,就对这条日志进行记录。
常见的日志级别如下(优先级依次升高)。

序号日志级别说明
1trace追踪,指明程序运行轨迹。
2debug调试,实际应用中一般将其作为最低级别,而 trace 则很少使用。
3info输出重要的信息,使用较多。
4warn警告,使用较多。
5error错误信息,使用较多。

输出格式
我们可以通过以下常用日志参数对日志的输出格式进行修改,如下表。

序号输出格式说明
1%d{yyyy-MM-dd HH:mm:ss, SSS}日志生产时间,输出到毫秒的时间
2%-5level输出日志级别,-5 表示左对齐并且固定输出 5 个字符,如果不足在右边补 0
3%logger 或 %clogger 的名称
4%thread 或 %t输出当前线程名称
5%p日志输出格式
6%message 或 %msg 或 %m日志内容,即 logger.info(“message”)
7%n换行符
8%class 或 %C输出 Java 类名
9%file 或 %F输出文件名
10%L输出错误行号
11%method 或 %M输出方法名
12%l输出语句所在的行数, 包括类名、方法名、文件名、行数
13hostName本地机器名
14hostAddress本地 ip 地址

修改默认的日志配置
我们可以根据自身的需求,通过全局配置文件(application.properties/yml)修改 Spring Boot 日志级别和显示格式等默认配置。

#日志级别
logging.level.net.biancheng.www=trace
#使用相对路径的方式设置日志输出的位置(项目根目录目录\my-log\mylog\spring.log)
#logging.file.path=my-log/myLog
#绝对路径方式将日志文件输出到 【项目所在磁盘根目录\springboot\logging\my\spring.log】
logging.file.path=/spring-boot/logging
#控制台日志输出格式
logging.pattern.console=%d{yyyy-MM-dd hh:mm:ss} [%thread] %-5level %logger{50} - %msg%n
#日志文件输出格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} === - %msg%n

自定义日志配置
在 Spring Boot 的配置文件 application.porperties/yml 中,可以对日志的一些默认配置进行修改,但这种方式只能修改个别的日志配置,想要修改更多的配置或者使用更高级的功能,则需要通过日志实现框架自己的配置文件进行配置。
Spring 官方提供了各个日志实现框架所需的配置文件,用户只要将指定的配置文件放置到项目的类路径下即可。

日志框架配置文件
Logbacklogback-spring.xml、logback-spring.groovy、logback.xml、logback.groovy
Log4j2log4j2-spring.xml、log4j2.xml
JUL(Java Util Logging) logging.properties

从上表可以看出,日志框架的配置文件基本上被分为 2 类:
1、普通日志配置文件,即不带 srping 标识的配置文件,例如 logback.xml;
我们将 logback.xml、log4j2.xml 等不带 spring 标识的普通日志配置文件,放在项目的类路径下后,这些配置文件会跳过 Spring Boot,直接被日志框架加载。通过这些配置文件,我们就可以达到自定义日志配置的目的。

2、带有 spring 表示的日志配置文件,例如 logback-spring.xml。
Spring Boot 推荐用户使用 logback-spring.xml、log4j2-spring.xml 等这种带有 spring 标识的配置文件。这种配置文件被放在项目类路径后,不会直接被日志框架加载,而是由 Spring Boot 对它们进行解析,这样就可以使用 Spring Boot 的高级功能 Profile,实现在不同的环境中使用不同的日志配置。

查看示例

13、Spring-boot-starter-web(Web启动器)

Spring MVC是Spring提供的一个基于MVC设计模式的轻量级Web开发框架,它提供了spring-boot-starter-web(Web场景启动器)来为Web开发予以支持。为我们提供了嵌入的Servlet容器以及SpringMVC的依赖,并为Spring MVC提供了大量的自动配置,可以适用于大多数Web开发场景。
Spring Boot 为 Spring MVC 提供了自动配置,并在 Spring MVC 默认功能的基础上添加了以下特性:

  • 引入了 ContentNegotiatingViewResolver 和 BeanNameViewResolver(视图解析器)
  • 对包括 WebJars 在内的静态资源的支持
  • 自动注册 Converter、GenericConverter 和 Formatter (转换器和格式化器)
  • 对 HttpMessageConverters 的支持(Spring MVC 中用于转换 HTTP 请求和响应的消息转换器)
  • 自动注册 MessageCodesResolver(用于定义错误代码生成规则)
  • 支持对静态首页(index.html)的访问
  • 自动使用 ConfigurableWebBindingInitializer

只要我们在 Spring Boot 项目中的 pom.xml 中引入了 spring-boot-starter-web ,即使不进行任何配置,也可以直接使用 Spring MVC 进行 Web 开发。

14、静态资源映射

Web 应用中会涉及到大量的静态资源,例如 JS、CSS 和 HTML 等。在Spring MVC 导入静态资源文件时,需要配置静态资源的映射;但在 SpringBoot 中则不再需要进行此项配置,因为 SpringBoot 已经默认完成了这一工作。
Spring Boot 默认为我们提供了 3 种静态资源映射规则:

  1. WebJars 映射
  2. 默认资源映射
  3. 静态首页(欢迎页)映射

WebJars映射
了解:为了让页面更加美观,让用户有更多更好的体验,Web 应用中通常会使用大量的 JS 和 CSS,例如 jQuery,Backbone.js 和 Bootstrap 等等。通常我们会将这些 Web 前端资源拷贝到 Java Web 项目的 webapp 相应目录下进行管理。但是Spring Boot 项目是以 JAR 包的形式进行部署的,不存在 webapp 目录,那么 Web 前端资源该如何引入到 Spring Boot 项目中呢?WebJars 可以完美的解决此问题,它可以 Jar 形式为 Web 项目提供资源文件。
WebJars 可以将 Web 前端资源(JS,CSS 等)打成一个个的 Jar 包,然后将这些 Jar 包部署到 Maven 中央仓库中进行统一管理
。当 Spring Boot 项目中需要引入 Web 前端资源时,只需要访问 WebJars官网,找到所需资源的 pom 依赖,将其导入到项目中即可。
所有通过 WebJars 引入的前端资源都存放在当前项目类路径(classpath)下的“/META-INF/resources/webjars/” 目录中。
Spring Boot 通过 MVC 的自动配置类 WebMvcAutoConfiguration 为这些 WebJars 前端资源提供了默认映射规则,部分源码如下。

public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
    } else {
        //WebJars 映射规则
        this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
        this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
            registration.addResourceLocations(this.resourceProperties.getStaticLocations());
            if (this.servletContext != null) {
                ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                registration.addResourceLocations(new Resource[]{resource});
            }
        });
    }
}

通过以上源码可知,WebJars 的映射路径为“/webjars/”,即所有访问“/webjars/”的请求,都会去“classpath:/META-INF/resources/webjars/”查找 WebJars 前端资源。

示例:
在项目中添加静态资源的依赖

<dependency>
    <groupId>org.webjars.npm</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>

导入的Jquery依赖jar目录如下
在这里插入图片描述
Jquery.js的访问地址为http://localhost:8081/webjars/jquery/3.6.0/dist/jquery.js
在这里插入图片描述
前端页面中也可以访问
在这里插入图片描述
默认静态资源映射
当访问项目中的任意资源(即“/**”)时,Spring Boot 会默认从以下路径中查找资源文件(优先级依次降低):
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/

静态首页(欢迎页)映射
静态资源文件夹下的所有 index.html 被称为静态首页或者欢迎页,它们会被被 /** 映射,换句话说就是,当我们访问“/”或者“/index.html”时,都会跳转到静态首页(欢迎页)。
注意,访问静态首页或欢迎页时,其查找顺序也遵循默认静态资源的查找顺序,即先查找优先级高的目录,在查找优先级低的目录,直到找到 index.html 为止。

15、SpringBoot定制SpringMVC

Spring Boot 抛弃了传统 xml 配置文件,通过配置类(标注 @Configuration 的类,相当于一个 xml 配置文件)以 JavaBean 形式进行相关配置。
Spring Boot 对 Spring MVC 的自动配置可以满足我们的大部分需求,但是我们也可以通过自定义配置类(标注 @Configuration 的类)并实现 WebMvcConfigurer 接口来定制 Spring MVC 配置,例如拦截器、格式化程序、视图控制器等等。
WebMvcConfigurer 是一个基于 Java 8 的接口,该接口定义了许多与 Spring MVC 相关的方法,其中大部分方法都是 default 类型的,且都是空实现。因此我们只需要定义一个配置类实现 WebMvcConfigurer 接口,并重写相应的方法便可以定制 Spring MVC 的配置。

方法说明
default void configurePathMatch(PathMatchConfigurer configurer) {}HandlerMappings 路径的匹配规则。
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}内容协商策略(一个请求路径返回多种数据格式)。
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}处理异步请求。
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}这个接口可以实现静态文件可以像 Servlet 一样被访问。
default void addFormatters(FormatterRegistry registry) {}添加格式化器或者转化器。
default void addInterceptors(InterceptorRegistry registry) {}添加 Spring MVC 生命周期拦截器,对请求进行拦截处理。
default void addResourceHandlers(ResourceHandlerRegistry registry) {}添加或修改静态资源(例如图片,js,css 等)映射;Spring Boot 默认设置的静态资源文件夹就是通过重写该方法设置的。
default void addCorsMappings(CorsRegistry registry) {}处理跨域请求。
default void addViewControllers(ViewControllerRegistry registry) {}主要用于实现无业务逻辑跳转,例如主页跳转,简单的请求重定向,错误页跳转等
default void configureViewResolvers(ViewResolverRegistry registry) {}配置视图解析器,将 Controller 返回的字符串(视图名称),转换为具体的视图进行渲染。
default void addArgumentResolvers(List resolvers) {}添加解析器以支持自定义控制器方法参数类型,实现该方法不会覆盖用于解析处理程序方法参数的内置支持;要自定义内置的参数解析支持, 同样可以通过 RequestMappingHandlerAdapter 直接配置 RequestMappingHandlerAdapter 。
default void addReturnValueHandlers(List handlers) {}添加处理程序来支持自定义控制器方法返回值类型。使用此选项不会覆盖处理返回值的内置支持;要自定义处理返回值的内置支持,请直接配置 RequestMappingHandlerAdapter。
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}用于配置默认的消息转换器(转换 HTTP 请求和响应)。
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}直接添加消息转换器,会关闭默认的消息转换器列表;实现该方法即可在不关闭默认转换器的起提下,新增一个自定义转换器。
default void configureHandlerExceptionResolvers(List resolvers) {}配置异常解析器。
default void extendHandlerExceptionResolvers(List resolvers) {}扩展或修改默认的异常解析器列表。

在 Spring Boot 项目中,有两种定制 Spring MVC的形式:
扩展 Spring MVC
如果 Spring Boot 对 Spring MVC 的自动配置不能满足我们的需要,我们还可以通过自定义一个 WebMvcConfigurer 类型(实现 WebMvcConfigurer 接口)的配置类(标注 @Configuration,但不标注 @EnableWebMvc 注解的类),来扩展 Spring MVC。这样不但能够保留 Spring Boot 对 Spring MVC 的自动配置,享受 Spring Boot 自动配置带来的便利,还能额外增加自定义的 Spring MVC 配置。
示例:

//实现 WebMvcConfigurer 接口可以来扩展 SpringMVC 的功能
//@EnableWebMvc   不要接管SpringMVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //当访问 “/” 或 “/index.html” 时,都直接跳转到登陆页面
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
    }
}

全面接管 Spring MVC
在一些特殊情况下,我们可能需要抛弃 Spring Boot 对 Spring MVC 的全部自动配置,完全接管 Spring MVC。此时我们可以自定义一个 WebMvcConfigurer 类型(实现 WebMvcConfigurer 接口)的配置类,并在该类上标注 @EnableWebMvc 注解,来实现完全接管 Spring MVC。
示例:

//实现 WebMvcConfigurer 接口可以来扩展 SpringMVC 的功能
@EnableWebMvc  // 完全接管SpringMVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //当访问 “/” 或 “/index.html” 时,都直接跳转到登陆页面
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/index.html").setViewName("login");
    }
}

16、SpringBoot中整合Thymeleaf

Thymealf介绍
SpringBoot整合Thymeleaf模版引擎,需要以下步骤;
1、引入Starter依赖,Thymeleaf启动器(开发环境)。

<!--Thymeleaf 启动器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2、在项目类路径(resources)下创建一个templates的目录,用于存放需要进行渲染的页面。

测试:
在templates目录下创建hello.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>欢迎使用Thymeleaf</h1>
</body>
</html>

编写Controller

@Controller
public class A {
    @RequestMapping("/h")
    public String m(){
        return "hello";//自动映射templates目标下的hello.html文件
    }
}

访问地址localhost:端口号/h,即可跳转到hello.html页面。

17、SpringBoot国际化

开发的软件需要能同时应对不同国家和地区的用户访问,并根据用户地区和语言习惯,提供相应的、符合用具阅读习惯的页面和数据,例如,为中国用户提供汉语界面显示,为美国用户提供提供英语界面显示。.国际化(Internationalization)简称I18n,其中I和n分别为首末字符,18则为中间的字符数。指软件开发时应该具备支持多种语言和地区的功能。

在 Spring 项目中实现国际化,通常需要以下 3 步:
编写国际化资源(配置)文件;
使用 ResourceBundleMessageSource 管理国际化资源文件;
在页面获取国际化内容

狂神说国际化

18、SpringBoot拦截器

拦截器可以根据URL对请求进行拦截,主要应用有登录校验、权限验证、乱码解决性能监控和异常处理等功能。
在 Spring Boot 项目中,使用拦截器功能通常需要以下 3 步:
定义拦截器;
注册拦截器;
指定拦截规则(如果是拦截所有,静态资源也会被拦截)。
定义拦截器
SpringBoot中定义拦截器十分简单,只需要实现HandlerInterceptor接口即可。
HandlerInterceptor定义的3个方法:

返回值类型方法声明描述
booleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)该方法在控制器处理请求方法前执行,返回值表示是否中断后续操作,返回true表示继续执行,flase表示中断后续操作
voidpostHandle(HttpServletReequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView)该方法在控制器处理方法调用之后,解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。
voidafterCompletion(HttoServletRequest request,HttpServletResponse response,Object handler,Exception ex)该方法实现资源清理、记录日志信息等工作

下例是一个登录的拦截器

package net.biancheng.www.componet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行前
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object loginUser = request.getSession().getAttribute("loginUser");
        if (loginUser == null) {
            //未登录,返回登陆页
            request.setAttribute("msg", "您没有权限进行此操作,请先登陆!");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        } else {
            //放行
            return true;
        }
    }
    /**
     * 目标方法执行后
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}", modelAndView);
    }
    /**
     * 页面渲染后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}", ex);
    }
}

注册拦截器
创建一个WebMvcConfigurer接口的配置类(使用了@Configuration注解的类),重写addInterceptors()方法,并在该方法中调用registry.addIntercetor()将自定义的拦截器注册到容器中。注意不要忘了在类的上方加上@Configuration注解将此类添加在SpringBoot的配置当中。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    ......
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor());
    }
}

指定拦截器规则

@Slf4j
@Configuration
public class MyConfig implements WebMvcConfigurer {
    ......
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        log.info("注册拦截器");
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") //拦截所有请求,包括静态资源文件
                .excludePathPatterns("/", "/login", "/index.html", "/user/login", "/css/**", "/images/**", "/js/**", "/fonts/**"); //放行登录页,登陆操作,静态资源
    }
}

addPathPatterns:该方法用于指定拦截路径,例如拦截路径为"/**",表示拦截所有请求,包括静态资源的请求。
excludePathPatterns:该方法用于排除拦截路径,即指定不需要被拦截器拦截的请求。
至此,拦截器的功能就添加完成了。

19、SpringBoot定制错误页面

方式一:自定义error.html页面
我们可以直接在模板引擎文件夹(/resources/templates)下创建error.html,覆盖SpringBoot默认的错误视图页面(WhiteLabel Error Page)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ERROR PAGE</title>
</head>
<body>
<h1 th:switch="${status}">Status:
    <span th:case="404">页面找不到了</span>
</h1>
<p>error:<span>${error}</span></p>
<p>timestamp<span th:text="${timestamp}"></span></p>
<p>message:<span th:text="${message}"></span></p>
<p>path:<span th:text="${path}"></span></p>
</body>
</html>

启动项目后,访问一个没有注册过的页面,报错以下错误。
在这里插入图片描述
方式二:自定义动态错误页面
如果 Sprng Boot 项目使用了模板引擎,当程序发生异常时,Spring Boot 的默认错误视图解析器(DefaultErrorViewResolver)就会解析模板引擎文件夹(resources/templates/)下 error 目录中的错误视图页面。

【精确匹配】
我们可以根据错误状态码(例如 404、500、400 等等)的不同,分别创建不同的动态错误页面(例如 404.html、500.html、400.html 等等),并将它们存放在模板引擎文件夹下的 error 目录中。当发生异常时,Spring Boot 会根据其错误状态码精确匹配到对应的错误页面上。
如下图在template下新建一个error目录,再在该error目录下创建一个404.html的页面,当发生404错误的时候就会显示该页面的信息。
在这里插入图片描述
【模糊查询】
我们还可以使用 4xx.html 和 5xx.html 作为动态错误页面的文件名,并将它们存放在模板引擎文件夹下的 error 目录中,来模糊匹配对应类型的所有错误,例如 404、400 等错误状态码以“4”开头的所有异常,都会解析到动态错误页面 4xx.html 上。

方式三:自定义静态错误页面
若SpringBoot项目没有使用模板引擎,SpringBoot的默认错误视图解析器(DefaultErrorViewResolver)则会解析静态资源文件夹下的error目录的静态错误页面。
在src/recources/static下的error目录中,创建一个名为404.html的静态错误页面。
自定义静态错误页面也有精确匹配与模糊匹配的分别与上面的动态错误页面相同。

20、SpringBoot注册Web原生组件

因为应用太少,比较偏门,不做详述。想了解的话这里点击学习教程

21、SpringBootJDBC访问数据库

对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 都默认采用整合 Spring Data 的方式进行统一处理,通过大量自动配置,来简化我们对数据访问层的操作,我们只需要进行简单的设置即可实现对书层的访问。本节,我们将学习如何在 Spring Boot 中使用 JDBC 进行数据访问。
导入 JDBC 场景启动器
Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的场景启动器(Starter),场景启动器中整合了该场景下各种可能用到的依赖,让用户摆脱了处理各种依赖和配置的困扰。

想要在 Spring Boot 中使用 JDBC 进行数据访问,第一步就是要在 pom.xml 中导入 JDBC 场景启动器:spring-boot-starter-data-jdbc,代码如下。

<!--导入JDBC的场景启动器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

导入数据库驱动

<!--导入数据库驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

配置数据源

#数据源连接信息
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/bianchengbang_jdbc
    driver-class-name: com.mysql.cj.jdbc.Driver

测试

package net.biancheng.www;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.sql.SQLException;
@SpringBootTest
class SpringBootJdbcApplicationTests {
    //数据源组件
    @Autowired
    DataSource dataSource;
    //用于访问数据库的组件
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Test
    void contextLoads() throws SQLException {
        System.out.println("默认数据源为:" + dataSource.getClass());
        System.out.println("数据库连接实例:" + dataSource.getConnection());
        //访问数据库
        Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `user`", Integer.class);
        System.out.println("user 表中共有" + i + "条数据。");
    }
}

22、SpringBoot整合Druid数据源

Spring Boot 2.x 默认使用 HikariCP 作为数据源,我们只要在项目中导入了 Spring Boot 的 JDBC 场景启动器,便可以使用 HikariCP 数据源获取数据库连接,对数据库进行增删改查等操作。

HikariCP 是目前市面上性能最好的数据源产品,但在实际的开发过程中,企业往往更青睐于另一款数据源产品:Druid,它是目前国内使用范围最广的数据源产品。

Druid 是阿里巴巴推出的一款开源的高性能数据源产品,Druid 支持所有 JDBC 兼容的数据库,包括 Oracle、MySQL、SQL Server 和 H2 等等。Druid 不仅结合了 C3P0、DBCP 和 PROXOOL 等数据源产品的优点,同时还加入了强大的监控功能。通过 Druid 的监控功能,可以实时观察数据库连接池和 SQL 的运行情况,帮助用户及时排查出系统中存在的问题,天生就是针对监控而生的 DB 连接池。

Druid 不是 Spring Boot 内部提供的技术,它属于第三方技术,我们可以通过以下两种方式进行整合:

  • 自定义整合 Druid (操作繁琐)
  • 通过 starter 整合 Druid (最优方案)

包括:
1、创建数据源
配置数据库连接
2、开启Druid内置监控页面
Druid 内置提供了一个名为 StatViewServlet 的 Servlet,这个 Servlet 可以开启 Druid 的内置监控页面功能, 展示 Druid 的统计信息,它的主要用途如下:
提供监控信息展示的 html 页面
提供监控信息的 JSON API
3、开启SQL监控
Druid 内置提供了一个 StatFilter,通过它可以开启 Druid 的 SQL 监控功能,对 SQL 进行监控。
4、开启防火墙
Druid 内置提供了一个 WallFilter,使用它可以开启防火墙功能,防御 SQL 注入攻击。
5、开启 Web-JDBC 关联监控
Druid 还内置提供了一个名为 WebStatFilter 的过滤器,它可以用来监控与采集 web-jdbc 关联监控的数据。
查看实现

24、SpringBoot整合Mybatis

MyBatis 是一个半自动化的 ORM 框架,所谓半自动化是指 MyBatis 只支持将数据库查出的数据映射到 POJO 实体类上,而实体到数据库的映射则需要我们自己编写 SQL 语句实现,相较于Hibernate 这种完全自动化的框架,Mybatis 更加灵活,我们可以根据自身的需求编写 sql 语句来实现复杂的数据库操作。

整合依赖

<!--引入 mybatis-spring-boot-starter 的依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

配置文件

###################################### MyBatis 配置######################################
mybatis:
  # 指定 mapper.xml 的位置
  mapper-locations: classpath:mybatis/mapper/*.xml
  #扫描实体类的位置,在此处指明扫描实体类的包,在 mapper.xml 中就可以不写实体类的全路径名
  type-aliases-package: net.biancheng.www.bean
  configuration:
    #默认开启驼峰命名法,可以不用设置该属性
    map-underscore-to-camel-case: true  

25、自定义Starter

starter 是 SpringBoot 中一种非常重要的机制,它可以繁杂的配置统一集成到 starter 中,我们只需要通过 maven 将 starter 依赖引入到项目中,SpringBoot 就能自动扫描并加载相应的默认配置。在一些特殊情况下,我们也可以将一些通用功能封装成自定义的 starter 进行使用

自定义starter的注意事项
1、命名规范
SpringBoot的starter是以spring-boot-starter-xxx的形式命名,第三方开发者应该用xxx-spring-boot-starter的形式命名,用于与SpringBoot生态提供的starter区分。如mybatis-spring-boot-starter。

2、模块规范
Spring Boot 官方建议我们在自定义 starter 时,创建两个 Module :autoConfigure Module 和 starter Module,其中 starter Module 依赖于 autoConfigure Module。当然,这只是 Spring Boot 官方的建议,并不是硬性规定,若不需要自动配置代码和依赖项目分离,我们也可以将它们组合到同一个 Module 里。

学习starter制作过程

SpringBoot 实现热部署

SpringBoot在IDEA中实现热部署

SpringBoot任务

1、异步任务
在SpringBoot中开启异步任务首先要在SpringBoot启动类上添加注解@EnableAsync,开启异步任务的支持。

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

然后在需要异步执行的方法上添加注解@Async,该注解下的方法会在主线程上开辟一条新的线程,从而实现异步执行。

@Async//告诉Spring这是一个异步的任务
public void hello(){
    System.out.println("数据正在处理...");
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("数据处理完成");
}

2、邮件任务

3、定时器任务
1.要配置定时任务,首先需要开启定时任务支持。

@SpringBootApplication
@EnableScheduling //开启定时任务的注解
public class SpringBootTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskApplication.class, args);
    }
}

2.在需要定时执行的方法上添加注解@Scheduled,cron表达式用来表示执行计时程序的时间。

//在一个特定的时间去执行这个方法~ Timer
//cron 表达式
//秒 分 时 日 月 周几
@Scheduled(cron = "50 45 11 * * ?")
public void t(){
    System.out.println("执行了定时任务");
}

点击查看
cron表达式详解
cron常用表达式
cron表达式在线生成器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值