一、Spring Boot 入门

Spring Boot 来简化Spring应用开发的一个框架,约定大于配置
Spring Boot 的底层用的就是Spring
访问官网:spring.io 再点击projects

1.背景

问题
J2EE笨重的开发,繁多的配置、低下的开发效率、复杂的部署流程,第三发技术集成难度大。
解决
“Spring全家桶”时代
Spring Boot -> J2EE一站式解决方案
Spring Cloud ->分布式整体解决方案
优点
快速创建独立运行的Spring项目以及与主流框架集成
使用嵌套式的Servlet容器,应用无需打成WAR包
starters自动依赖与版本控制
大量的自动配置简化开发,也可修改默认值
无需配置XML,无代码生成,开箱即用
准成产环境的运行时应用监控
与云计算的天然集成
微服务简介
martinfowler
微服务:架构分格
一个应用应该是一组小型服务;可以通过http的方式进行互通

2.环境准备

jdk1.8
maven3.x
intellijIDEA
SpringBoot

MAVEN设置:
给maven的setting.xml配置文件的profiles标签添加
(F:\jsp\apache-maven-3.6.1-bin\apache-maven-3.6.1\conf)

jdk-1.8

 <activation>
<activeByDefault>true</activeByDefault>
		<jdk>1.8</jdk>
</activation>

<properties>
<mavenpiler.source>1.8</mavenpiler.source>
<mavenpiler.target>1.8</mavenpiler.target>
<mavenpilerpilerVersion>1.8</mavenpilerpilerVersion>
2.IDEA的默认修改: 修改IDEA的默认maven ,具体看下面的博客https://blog.csdn/weixin_43034040/article/details/103835125 HelloWorld项目 浏览器发送hello请求,服务器接收请求并处理,响应Hello World 字符串 第1步.创建一个maven工程(jar) create new project ->maven->next 第2步.导入spring boot相关依赖 来到spring boot 官网
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

第3步 .编写一个主程序:启动Spring Boot

package com.atguigu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {
    public static void main(String[] args) {
        //Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);

    }
}

第4步.编写相关的Controller、Service

package com.atguigu.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @ResponseBody
    @RequestMapping("/hello")
    public  String hello(){
        return "Hello world";
    }
}

如果很多发那个发都是RESTAPI的方式,即发送数据给浏览器,而不是页面跳转,则

@ResponseBody可以放在类外
@ResponseBody
@Controller
public class HelloController {
    
    @RequestMapping("/hello")
    public  String hello(){
        return "Hello world";
    }
}
@ResponseBody
@Controller
两个合并:@RestController
//@ResponseBody
//@Controller
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public  String hello(){
        return "Hello world";
    }
}

第5步.运行并访问
运行主程序
浏览器输入:http://localhost:8080/hello

第6步.简化部署
就算没有装tomcat环境也可以运行
a.导入插件:
11. 开发你的第一个 Spring Boot Application

www.docs4dev

将以下代码添加到pom中

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

b.打包
点击Idea右边的maven ->Lifecycle->package
此时maven介入进行打包,打包的地址为
Building jar:
G:\java\spring-boot-01-helloworld\target\spring-boot-01-helloworld-1.0-SNAPSHOT.jar

jar包内容:
BOOT-INF\classes:自己写的类
BOOT-INF\lib:maven依赖导入的,包含了tomcat
c.命令行运行
在jar包所在目录下,命令行运行:java -jar spring-boot-01-helloworld-1.0-SNAPSHOT.jar
d.浏览器运行
浏览器输入:http://localhost:8080/hello
3.HelloWorld项目解析
POM文件
父项目

org.springframework.boot
spring-boot-starter-parent
1.5.9.RELEASE


查看spring-boot-starter-parent,它也有有父项目

org.springframework.boot
spring-boot-dependencies
1.5.9.RELEASE
…/…/spring-boot-dependencies

查看spring-boot-dependencies,有定义了每一个依赖的版本,真正管理Spring Boot应用里的所有应用版本


<activemq.version>5.14.5</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.59</appengine-sdk.version>
<artemis.version>1.5.5</artemis.version>



导入starters启动器
导入


org.springframework.boot
spring-boot-starter-web


spring-boot-starter:spring-boot场景启动器
spring-boot-starter-web:帮我们导入web模块正常运行所依赖的组件。
starters启动器
参考官网:
Spring Boot Reference Guide

docs.spring.io

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

/**
 * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {
    public static void main(String[] args) {
        //Spring应用启动起来,run()里的类必须是@SpringBootApplication标注的类
        SpringApplication.run(HelloWorldMainApplication.class,args);

    }
}
@SpringBootApplication(即Spring Boot 应用)
进入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
Spring Boot的配置类
标注在某个类上,表示是一个SpringBoot的配置类,
再点进去
发现@Configuration,这就是spring的配置注解。
@EnableAutoConfiguration
开启自动配置功能;
以前需要配置的东西,现在spring boot帮我们自动配置,查看EnableAutoConfiguration有:
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage :自动配置包
进去查看:
有@Import({Registrar.class}),是Spring的底层注解,给容器导入自已组件
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}

将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
@Import({EnableAutoConfigurationImportSelector.class}):导入哪些选择器,将所有需要导入的组件以全类名的方式返回;这些组件会被添加到容器中;会给容器导入非常多的(见下图)自动配置类(xxxAutoConfigration);就是给容器中导入这个场景组要的所有组件,并配置包这些
extends AutoConfigurationImportSelector
public String[] selectImports(AnnotationMetadata annotationMetadata) {

4.使用Spring Initialier快速创建Spring Boot项目
选择我们需要的模块,向导会联网创建Spring Boot项目。
步骤
选择Spring Initialier

输入Group、Artifact和 package

选择功能模块

删除多余的

失败了,先跳过。
哈哈,我知道代替方法了,
1.使用https://start.spring.io/生成有错误的的代码,错误之处在于版本,不知版本哪里错了,以后再说哦。
2。将版本改为1.5.9.RELEASE
出现问题:
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
解决:点击test,导入
自动增加的内容
默认生成的Spring boot 项目:

主程序已经生成好了,我们只需要我们自己的逻辑
resources文件夹中目录结构
static:所有的静态资源;js,css,图片
templates:保存所有的模板页面;(Spring Boot默认jar包使用嵌套式的Tomcat,默认不支持JSP页面);可以使用模板引擎
application.properties:Spring Boot 应用的配置文件
application.properties
想更改端口号:
application.properties文件里添加:
server.port=8081
二、配置文件
1.配置文件
SpringBoot使用一个全局的配置文件,配置文件名是固定的。
application.properties
application.yml
配置文件的作用:修改SpringBoot自动配置的默认值;
YAML( YAML Aint Markup Language) YAML A Markup Language:是一个标记语言 YAML isnt Markup Language:不是一个标记语言
标记语言:
以前的配置文件大多是xxx.xml文件;
YAML:UI数据为中心,比json和xml更适合做配置文件
想更改端口号的三种文件方式
properties:
server.port=8081
YAML:
server :
port : 8081
XML:

8081

比较:XML造成大量文件空间的浪费,YAML非常简洁
2.YAML语法
1.基本语法
k(空格):(空格) v 表示一对键值对
以空格的缩进来控制层级关系;只要左对齐的一列数据,都是同一层级的。
server :
port : 8081
path : /hello
属性和值是大小写敏感的
2.值的写法
字面量 : 普通的值(数字,字符串,布尔)
k : v
字符串默认不加单引号或者双引号;
双引号:不会转义字符串里面的特殊字符
单引号:会转义
对象、Map(属性和值)(键值对):
v是对象时
friends :
lastName : zhangsan
age : 20
或者行内写法
friends : {lastName : zhangsan , age : 20}
数组(List、Set)
用 - 值表示数组中的一个元素
pets:

  • cat

  • dog

  • pig
    或者行内写法
    pets: [cat,dog,pig]
    3.@ConfigurationProperties
    yaml和properties的写法项目参考:G:\java\spring-boot-02-config-2
    4.@Value
    在spring基础中



    @Value就是上面代码的value
    @Value的使用
    使用了@Value后就不需要写@ConfigurationProperties
    //@ConfigurationProperties(prefix = “person”)
    public class Person {
    @Value("${person.last-name}")
    private String lastName;

    @Value("#{11*2}")
    private int age; #代表22

    private Date birth;

    @Value(“true”)
    private boolean boss;
    private Map<String,Object> maps;
    private List lists;
    private Dog dog;
    5.@Conf…和@Value两者比较

配置文件yml还是properties都可以,
都是从全局配置文件中获取值
简单的用@Value
复杂的用@ConfigurationProperties
@Conf…的数据效验
@Component
@ConfigurationProperties(prefix = “person”)
@Validated //数据效验
public class Person {
@Email
private String lastName;//必须输入邮件类型的字符串
6.@PropertySource和@ImportResource
@PropertySource
作用:加载指定的配置文件;
@PropertySource(value = {“classpath:/person.properties”}) #指定了person.properties
@Component
@ConfigurationProperties(prefix = “person”)
public class Person {
private String lastName;
@ImportResource
作用:导入Spring的配置文件,让配置文件里面的内容生效
自己添加的bean.xml,springboot才不鸟你,所以要连接起来
@ImportResource标注在一个配置类上
不太好的写法:
@ImportResource(locations = {“classpath:beans.xml”})
@SpringBootApplication
public class SpringBoot02Config2Application {

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

}
SpringBoot推荐:给容器中添加组件的方式,使用全注解的方式
配置类====配置文件
使用@Bean给容器中添加组件
@Configuration
public class MyAppConfig {
//将方法添加到容器中:容器中这个组件默认的id为方法名
@Bean
public HelloService helloService(){
System.out.println(“配置类@Bean给容器中添加组件了…”);
return new HelloService();
}
}
7.占位符(数据插入)
1.随机数
h t t p : / / r a n d o m . i n t 2. 占 位 符 获 取 之 前 配 置 的 值 如 果 之 前 没 有 配 过 该 值 , 可 以 设 置 冒 号 : 指 定 默 认 值 p e r s o n . d o g . n a m e = {http://random.int} 2.占位符获取之前配置的值 如果之前没有配过该值,可以设置冒号:指定默认值 person.dog.name= http://random.int2.person.dog.name={person.last-name}_dog
person.dog.name=${person.last-name:zhangsan}_dog #设置默认值
8.Profile(配置文件选择)
1.多Profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
从而实现动态切换。
默认是使用:application.properties
2.yml支持多文档块方式
server:
port: 8081
spring:
profiles:
active: dev

server:
port: 8083
spring:
profiles: dev

server:
port: 8084
spring:
profiles: prod
使用上面的
spring:
profiles:
active: dev
代码进行切换
3.激活指定profile
注意:命令行里激活方法和配置文件的种类无关
创建不同的配置文件。

方式1:配置文件
在配置文件中指定:spring.profiles.active=dev
方式2:命令行
在命令行里指定的配置文件:
–spring.profiles.active=dev
步骤
1.下拉,选择edict configrations

2.program arguments输入–spring.profiles.active=一种模式

方式2的另一种方法:项目编写结束后,使用maven打包,命令行运行包
步骤
1.打包

2.运行
cd 到G:\java\spring-boot-02-config-2\target
命令行运行:
java -jar spring-boot-02-config-2-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

方式3:虚拟机参数
-Dspring.profiles.active=dev
步骤
1.下拉运行按钮,选择edict configrations
2.设置后运行即可

9.配置文件加载位置
1.优先级
spring boot启动会扫描一下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
file:./config
file:./
classpath:/config/
classpath:/
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,实现互补配置,高优先级配置内容覆盖低优先级配置内容
我们可以通过spring.config.location来改变默认配置
优先级具体如下(高->低):

2.默认位置更改
使用spring.config.location
是在项目打包好后,我们可以使用命令行参数的形式,启动项目的时候来制定配置文件的;指定的配置的文件和默认加载的配置文件会共同起作用,形成互补配置。
我试过不共存啊?????????????????
java -jar spring-boot-02-config02-0.0.1-SNAPSHOT.jar --spring.config.location=C:\Users\Willian\Desktop\appl
ication.properties
10.外置配置加载顺序
官方文档地址:
Spring Boot Reference Guide

docs.spring.io

1.命令行Spring Boot Reference Guide1.命令行
java -jar spring-boot-02-config02-0.0.1-SNAPSHOT.jar --server.port=8087
多个参数用空格隔开;–配置值=值
当jar压缩包同路径下有application.properties时,会自动发运行加载
2.来自java:comp/env的NDI属性
3.Java系统变量 (System.getProperties()).
4.操作系统变量
5.RandomValuePropertySource 配置的 random.*属性值
先加载带profile
6.jar包外部的application-{profile}.properties或application.yaml(带spring.profile)配置文件
7.jar包内部的application-{profile}.properties或application.yaml(带spring.profile)配置文件
再来加载带不带profile
8.jar包外部的application.properties或application.yaml(不带spring.profile)配置文件
9.jar包内部的application.properties或application.yaml(不带spring.profile)配置文件
10.@Configration注解类上的@PropertySource
11.通过SpringApplication.setDefaultProperties指定默认属性
11.自动配置原理
配置文件到底写什么?怎么写?自动配置原理;
配置参照

自动配置原理
注意是1.5.9版本。2.2.0无EnableAutoConfigurationImportSelector
springboot启动的时候,加载主配置类,而且开启制动配置功能@EnableAutoConfiguration
利用EnableAutoConfigurationImportSelector给容器中导入一些组件
查看selectImports()方法
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
SpringFactoriesLoader.loadFactoryNames()
扫描jar包类路径下的META-INF/spring.factories,
把扫描到的这些文件的内容包装成properties的对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,让后把他们添加到容器中
所以一句话就是
将类路径下的 META-INF/spring.factories里面的配置的所有EnableAutoConfiguration值加入到容器中
每一个xxxAutoConfiguration类都是容器的一个组件,都加入到容器中,用他们来做自动配置
每一个自动配置类进行自动配置类功能;
以HttpEncodingAutoConfiguration为例

根据当前不同的条件判断,决定这个配置类是否生效
一旦这个配置类生效,这个配置类就会给容器添加各种组件;这些组件的属性是从对应的properties类中获取,这些类里面的每个属性又是和配置文件绑定的;
@Configuration //这是一个配置类
@EnableConfigurationProperties({HttpEncodingProperties.class})//下有解释,把HttpEncodingProperties加入到ioc容器中

@ConditionalOnWebApplication//@Conditional是spring底层。指定条件配置生效;此处判断是否为web应用,如果是,生效

@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有无该类,CharacterEncodingFilter是springMVC中进行乱码解决的过滤器

@ConditionalOnProperty(//判断配置文件是否存在某个配置spring.http.encoding,不配置或配置返回true
prefix = “spring.http.encoding”,
value = {“enabled”},
matchIfMissing = true
)
//如果上面的条件都成立,则执行下面类
public class HttpEncodingAutoConfiguration {

//他已经和SpringBoot的配置文件映射了
private final HttpEncodingProperties properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿@EnableConfigurationProperties
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
    this.properties = properties;
}

@Bean	//为容器添加一个组件,组件的某些值需要在properties中获取
@ConditionalOnMissingBean({CharacterEncodingFilter.class})
public CharacterEncodingFilter characterEncodingFilter() {
    CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
    filter.setEncoding(this.properties.getCharset().name());
    filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
    filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
    return filter;
}

@EnableConfigurationProperties({HttpEncodingProperties.class})
启用指定类(HttpEncodingProperties)的EnableConfigurationProperties功能
所有在配置文件中能配置的属性都是在xxxProperties类中封装着;
进入HttpEncodingProperties查看有
@ConfigurationProperties(
prefix = “spring.http.encoding” //从配置文件中获取指定值和bean的属性
)
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET = Charset.forName(“UTF-8”);
精髓:
SpringBoot启动会加载大量的配置类
我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
再来坑自动配置类中配置 哪些组件;只要我们要用的组件有,我们就不需要配置
给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值
xxxAutoConfigration:自动配置类
给容器添加组件(里面有@Bean)
xxxProperties:封装配置文件中的相关属性
细节:conditional
@Conditional是指定条件成立

自动配置类必须在一定条件下才生效
怎么知道哪些类生效?
10.生效配置类查看
可以通过配置debug=true属性

三、日志
1.日志框架
小张用System.out.println("");将关键数据打印在控制台;现在去掉,卸载文件里
用框架记录运行信息;日志框架,zhanglogging.jar
升级,异步,自动…,zhanglogging-good.jar
更换框架,修改API,zhanglogging-perfect.jar
参考JDBC–数据库驱动;写一个统一的接口层
市面上的日志框架
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j、、

挑选
日志门面:SLF4J
日志实现:Logback
SpringBoot:底层是Spring框架,Spring架构默认是JCL;
SpringBoot选用SLF4J和Logback
2.SLF4j使用
1.如何在系统中使用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);
logger.info(“Hello World”);
}
}

每一个日志的实现框架都有知己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架的配置文件
2.遗留问题
如果有个系统a,使用的是slf4j+logback,它整合了Spring、Hibernate、MyBatis…,他们用了不同的日志框架,如何统一?
统一日志记录,即使是别的框架,和我一起统一进行输出。

核心总结:如何让系统中所有的日志都统一到slf4j?
1.将系统中的其他日志框架先排除出去;
2.用中间包来替换原来的日志框架
3.再来导入slf4j其他的实现
3.SpringBoot日志关系

总结:
springboot底层也是使用slf4j+logback方式进行日志记录
springboot也把其他的日志替换成slf4j
虽然表面上用的是其他的包,但是其他包的内部引用的还是slf4j

如果我们要引入其他框架,IDing要把这个框架的默认日志依赖移除掉
可以发现springboot2.0之前的版本,springboot是直接排除(exclusions)底层Spring的comons-logging(JCL)框架
在springboot2.0之后用的是Spring5,Spring5用的是slf4j,所以就无需排除了

3.日志使用
1.默认配置
SpringBoot 默认帮我们配置好了日志;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package com.atguigu.springboot;
import org.junit.jupiter.api.Test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringBoot03LoggingApplicationTests {

//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
void contextLoads() {
    //日志级别
    //又低到高
    //可以调整输出的日志级别
    logger.trace("这是trace日志...");
    logger.debug("这是debug日志...");
    //默认是info级别
    logger.info("这是info日志...");
    logger.warn("这是warn日志...");
    logger.error("这是error日志...");
}

}

更改默认级别:
logging.level.atguigu=trace #com.atguigu是指定地方
#当前项目下生成
logging.file.name=springboot.log
#G盘下生成
#logging.file.name=G:/springboot.log
#根目录(G盘)下生成
#logging.file.path=/spring/log

#控制台输出的日志格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS}[%thead] %-5level %logger{50} - %msg%n}
#指定文件中的日志输出格式
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS}[%thead] === %-5level === %logger{50} === %msg%n}
日志输出格式:
时间:%d{yyyy-MM-dd HH:mm:ss.SSS}
线程名:%thead
字符宽度限制:%-5 表示从左显示5个字符宽度
长度分割:%logger{50} 表示以50个字符为单位进行分割
日志消息:%msg
换行:%n
2.指定配置
官方教程:
Spring Boot Reference Guide
给类路径下放上每个日志框架自己的配置文件即可;Springboot就不适用他默认配置的了

logback.xml:直接被日志框架识别,相当于绕过springboot,
建议使用logback-spring.xml,可以使用下面的配置,指定某个配置只在某个环境下生效


4.切换日志框架 https://www.bilibili/video/av38657363?p=26 不常用,用到再学 四、Spring Boot与Web开发 1.SpringBoot对静态资源的映射规则 public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); if (!registry.hasMappingForPattern("/webjars/**")) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); }
            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
            if (!registry.hasMappingForPattern(staticPathPattern)) {
                this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }

        }
    }

1)、所有/Webjars/都是从classpath:/META-INF/resources/webjars/**找资源
Webjars:以jar包的方式引入静态资源
https://www.webjars/

www.webjars

再在项目里导入

访问jquery.js
localhost:8080/webjars/jquery/3.3.1/jquery.js

至此,全文完毕,码字不易,能看到这里的小伙伴都是积极又认真的同学,帮忙点个关注分享下再走吧,多谢!

更多推荐

全网最细致的SpringBoot实战教程,超适合新手小白入坑学习