Spring Boot学习笔记
一、Spring Boot入门
1.Spring Boot介绍
Spring Boot 是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
Spring Boot特性
1.1特性介绍
- 创建独立的Spring应用程序
- 嵌入的Tomcat,无需部署WAR文件
- 简化Maven配置
- 自动配置Spring
- 提供生产就绪功能,如指标,健康检查和外部配置
- 开箱即用,没有代码生成,也无需XML配置。
1.2 特性理解
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置,同时也可以修改默认值来满足特定的需求。
- 提供了一些大型项目中常见的非功能特性,如嵌入式服务器、安全、指标、健康检测、外部配置等。
- Spring Boot并不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式。
2.微服务
- 微服务是一种架构风格
- 提倡在开发应用时,一个应用应该是一组小型服务;可以通过HTTP的方式进行互通
2.1单体应用
- All In One ,
- 是传统的架构,
- 优点:开发、部署、运维要简单,
- 缺点:牵一发动全身,不适合大型应用
- 在多个服务器上复制这个单体进行扩展
2.2 微服务
- 一个微服务架构把每个功能元素放进一个独立的服务中
- 通过跨域服务器分发这些服务进行扩展,只在需要时进行扩展
- 每一个功能元素都是一个可以替换和独立升级的软件单元
3.环境准备
- Spring Boot推荐使用jdk的版本:1.7及以上
- maven:3.3及以上版本
- intellij idea
- Spring Boot
Maven设置:
给maven的settings.xml配置文件的profiles标签添加
表明使用jdk1.8进行开发
1 <profile> 2 <id>jdk-1.8</id> 3 <activation> 4 <activeByDefault>true/ activeByDefault> 5 <jdk>1.8</jdk> 6 </activation> 7 <properties> 8 <maven. compiler .source>1。8</maven.compiler.source> 9 <maven. compi ler. target>1.8</maven.compller.target> 10 <maven. compiler. compilerverslon>1.8</maven.compiler.compllerversion> 11 </propert1es> 12 </profile>
Idea设置
进入设置页面 Ctrl+Alt+S
Build,Execution,Deployment–>Build Tools–>Maven
设置maven为本地的maven, 库也为本地maven库
4.Spring Boot HelloWorld
一个功能:
浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串;
4.1、创建一个maven工程;(jar)
4.2、导入spring boot相关的依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
4.3、编写一个主程序;启动Spring Boot应用
/** * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用 */ @SpringBootApplication public class HelloWorldMainApplication { public static void main(String[] args) { // Spring应用启动起来 SpringApplication.run(HelloWorldMainApplication.class,args); } }
4.4、编写相关的Controller、Service
@Controller public class HelloController { @ResponseBody @RequestMapping("/hello") public String hello(){ return "Hello World!"; } }
4.5、运行主程序测试
4.6、简化部署
<!-- 这个插件,可以将应用打包成一个可执行的jar包;-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
将这个应用打成jar包,直接使用java -jar的命令进行执行;
5.Hello World 的探究
1)pom文件
a.父项目
1 <parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-parent</artifactId> 4 <version>2.2.0.RELEASE</version> 5 <relativePath/> <!-- lookup parent from repository --> 6 </parent>
其中有各种依赖的版本,Spring Boot 通过此父项目真正管理Spring Boot里面的所有依赖版本(Spring Boot的依赖仲裁中心)
以后导入依赖不需要版本,(没有depenencies中依赖管理的需要自己声明版本号)
b.导入的依赖
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-web</artifactId> 4 </dependency>
spring-boot-stater-web
spring-boot-stater:Spring Boot 场景启动器:帮我们导入了web模块正常运行的组件
Spring Boot将所有的功能都抽取出来,做成一个个的staters(启动器),只需要在项目中引入这些启动器,相关的依赖就能自动导入
2)主程序类,主入口类
1 @SpringBootApplication 2 public class CaitApplication { 3 4 public static void main(String[] args) { 5 SpringApplication.run(CaitApplication.class, args); 6 } 7 8 }
@SpringBootApplication 核心注解,标注在某个类上说明这个类是Spring Boot的主配置类,Spring Boot 一个运行这个类的main方法来启动应用:
1 @Target({ElementType.TYPE}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @SpringBootConfiguration 6 @EnableAutoConfiguration 7 @ComponentScan( 8 excludeFilters = {@Filter( 9 type = FilterType.CUSTOM, 10 classes = {TypeExcludeFilter.class} 11 ), @Filter( 12 type = FilterType.CUSTOM, 13 classes = {AutoConfigurationExcludeFilter.class} 14 )} 15 ) 16 @ConfigurationPropertiesScan 17 public @interface SpringBootApplication {
-
@SpringBootConfiguration Spring Boot 的配置类;
- 标注在某个类上,表示这是一个Spring Boot 的配置类
- @Configuration 配置类上来标注这个注解;(Spring4.X)
- 配置类————配置文件;
-
@EnableAutoConfiguration 开启自动配置功能;
-
以前我们需要配置的东西,Spring Boot 帮我们自动配置;
-
@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效
- @AutoConfigurationPackage : 自动配置包
- @**Import({AutoConfigurationImportSelector.class})**Spring的底层注解,给容器中导入一个组件;导入的组件有AutoConfigurationImportSelector.class
-
1 @Target({ElementType.TYPE}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @AutoConfigurationPackage 6 @Import({AutoConfigurationImportSelector.class}) 7 public @interface EnableAutoConfiguration {
6.使用Spring Initializer快速创建Spring Boot 项目
SpringBoot学习第一步:搭建基础
IDEA对SpringBoot的项目支持可以说是点击就能完成基础的搭建,
流程如下
1.左上角File选项,New project,选择Spring Initializr

2.设置项目信息,Group 会自动创建Group文件夹,包含项目的代码;Artifact 的名字必须使用小写与下划线构成!!

3.选择web项目,右上角可以选择SpringBoot 的版本,一定要使用relese版本(正式版),不要使用SNAPSHOT版本

4.确定project的名字与位置,名字就是项目文件夹的名字

点击finish就好啦,一个SpringBoot+Maven项目就搞定了,最后创建三个基础包!

默认生成的Spring Boot 项目:
- 主程序已经生成,我们只需要我们自己的逻辑
- resouces文件夹中目录结构
- static:保存所有的静态资源:js,css,images;
- templates:保存所有的模板页面:(Spring Boot 默认jar包嵌入式的Tomcat,默认不支持Jsp页面);可以使用模板引擎(freemarker、thymeleaf);
- application.properties:Spring Boot 应用默认配置文件
二、Spring Boot 配置
1. 配置文件
Spring Boot 默认使用两种配置文件
- application.properties
- application.yml
配置文件的作用:修改Spring Boot自动配置的默认值;Spring Boot在底层自动配置好
YAML(YAML Ain’t Markup Language )语言的文本,
- YAML A Markup Language :是一个标记语言
- YAML isn’t Markup Language : 不是一个标记语言(XML类型标记文件)
标记语言:
- 以前的标记语言大多数使用的是 XXXX.xml
- YAML :以数据为中心,比json、xml等更适合做配置文件
2. YAML语法
1)基本语法
K:(空格)Value 表示一对键值对(空格必备)
以**空格**的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
server: port: 8081 path: /hello
属性与值也是大小写敏感的
2)值的写法
字面量:普通的值(数字,字符串,布尔)
key: value (中间有空格)字面直接来写;
-
字符串默认不用加上单引号和双引号
-
“”:双引号不会转义字符串里面的特殊字符;特殊字符会作为本身想表达的意思
- example: “zhangsan \n list”:输出:zhangshan (换行) list
-
‘’:单引号 会转义特殊字符,特殊字符最终只是一个普通的字符串数据
-
example: “zhangsan \n list”:输出:zhangshan \n list
-
-
对象、Map(属性和值)(键值对)
key: value
对象还是key: value的方式
example: create a object with propertities : lastName age
friends:
lastName: zhangshan
age: 22
行内写法:用一行表示
friends: {lastName: zhangshan , age: 18}
数组(List、Set):
用-值表示数组中的一个元素
pets: -cat -dog -pig
行内写法:
pets: [cat,dog,pig]
附:Spring Boot单元测试
可以在测试期间很方便的类似编码一样进行自动注入容器的功能
package com.cait.cait; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class CaitApplicationTests { @Autowired 要进行测试的类 @Test void contextLoads() { 进行操作 } }
3. 通过配置文件注入
1) 数据绑定到基础数据类型
@Value
String LastName;
是Spring 底层的一个注解,
对应的xml
<bean class="person">
<property name="LastName" value="字面量/${key}/#{SpEL}"></property>
</bean>
2) 将数据绑定到类中 含配置文件与类绑定的方法
注: prefix必须全部为小写,配置的类名不能使用大写!!!!!,如 subMit是错误的!!
首先类与配置文件要对应,在类前注释 @ConfigurationProperties(prefix=“pets”)
-
@ConfigurationProperties 告诉SpringBoot将本类中的所有属性和配置文件中相关属性进行绑定;
-
perfix=“pets”:配置文件中,该前缀下面的所有属性,进行一一映射
-
若报错,点击提示,官方说明应该添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
-
只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
-
添加@Component注解加入容器组件
总结:导入配置文件处理器,以后进行配置文件操作就有提示,类中属性的名要对应,类名可以不同,加入注解@ConfigurationProperties(prefix = “属性的前缀”)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
配置文件少用中文!!!
若输出为乱码,原因是idea使用的是utf8
打开Setting,搜索file encoding(文件编码),选择UTF8,同时选择需要在运行时转译为ascii
- Transparent native to ascii conversion
3) @Value 获取值和 @ConfigurationProperties获取值的比较
| 类型 | @ConfigurationProperties | @Value |
|---|---|---|
| 功能 | 批量注入配置文件中的属性 | 一个个指定 |
| 松散绑定(松散语法) | supported | unsupported,要严格对应名 |
| SpEL | unsupported | supported |
| JSR303 | supported | unsupported |
| 复杂类型封装 | supported | unsupported, only simple type is permitted |
配置文件yml于properties他们都能获取到值
- 如果说,我们只是在某个业务逻辑中需要获取一下文件中的某项值,使用@Value
- 如果单独写了一个JavaBean来匹配配置文件中的值,使用@ConfigurationProperties
4) 配置文件注入值数据校验
- 导入JSR303,在配置用的Bean上添加@Validated
- Bean中属性上添加判断注解
- @Email 就是邮箱校验
- @NotNull是非空注解
- Spring boot @Validated注解以及配合@Valid的使用
- @Validated注解使用
5) @PropertySource & @ImportResource
-
@PropertySource:加载指定的配置文件(非默认的application.yml)
-
参数Value指文件,encoding指编码,也很重要!!!
注:@PropertySource默认只能支持properties文件!!!!,
解决方案:SpringBoot配置文件@PropertySource 同时支持properties文件与yaml(yml)
6)Spring配置文件注入
a. @ImportResource: 导入Spring配置文件,让配置文件里面的内容生效;
想让Spring的配置文件生效,加载进来;将@ImportResouce标注在一个类上
@ImportResource(locations= {"classpath:bean.xml"})

导入Spring配置文件:beans.xml并使其生效
b. Spring Boot 推荐给容器添加组件的方式
-
配置类=======Spring 配置文件
-
使用@Bean添加
1 package com.jirath.springboot_learn.config; 2 3 import com.jirath.springboot_learn.service.HelloService; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 7 /** 8 * '@Configuratoin' point out that current object is a Configuration Class,which used to replace the Spring Configuration file before. 9 */ 10 @Configuration 11 public class MyConfig { 12 /** 13 * add current function's returned value to the ContextContainer, 14 * the id of the module in this ContextContainer is the name of function; 15 * @return the object which used to build a Bean 16 */ 17 @Bean 18 public HelloService helloService(){ 19 return new HelloService(); 20 } 21 }
4.配置文件占位符
RandomValuePropertySource: 配置文件中可以使用随机数
random.value 、{random.value}、random.value、{random.int}、random .long 、{random.long}、random.long、{random.int(10)}、random .in [ 1024 , 65536 ] 、{random.int[1024,65536]}、random.int[1024,65536]、{random.uuid}
属性配置占位符
app.name=MyApp app.description=${app.name} is a Spring Boot application
-
可以在配置文件中引用前面配置过的属性(优先级前面配置过的这里都能用)
-
${app.name:defultValue}来指定找不到属性时的默认值
![]()
-
若引用的值不存在,SpringBoot会默认将{}中间的值作为value
用${person.name:(defult)}可以设置默认为defult
5.Profile
在开发过程中会遇到开发和实际生产时项目的配置是不同的情况,应对这种情况,Spring设置了Profile,
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境
1)多Profile文件
我们在主配置文件编写的时候,文件名可以是 application-(profile).properties/yml
!!!注意,文件的profile必须在三个字符以内,否自无法作为配置文件!!
默认使用application.properties的配置:
2)yml支持多文档块方式
spring: profiles: active: dev --- server: port: 8081 spring: profiles: dev --- server: port: 8081 spring: profiles: prod
3)激活指定Profile
spring.profiles.active=dev
-
-
命令行:
-
–spring.profile.active=dev
-
idea测试方法
-

-
-
打包:
- 打开maven选项,Lifecycle->package
-
- 虚拟机方法
-Dspring-profiles.active=dev

6.配置文件的加载位置
spring boot 启动会扫描以下位置的application.properties / yml 文件作为Spring Boot的默认配置文件
- file:./config
- file:./
-
以上两种是在当前项目路径下,即与src同级
-
classpath:/config/
-
classpath:/
-
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载
-
高级优先配置内容会覆盖低级优先配置相同的内容,同时满足配置互补
-
我们也可以通过配置spring.config.location来改变默认配置
-
- 项目打包好了以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的位置;指定配置文件和默认加载的这些配置文件共同起作用,形成互补配
7.Spring Boot 外部配置加载顺序
Spring Boot也可以从以下位置加载配置;优先级从高到低
优先加载带Profile,jar包外部的
-
命令行参数
-
来自java:comp/env的NDI属性
-
Java系统属性(System.getProperties())
-
操作系统环境变量
-
RandomValuePropertySource配置的random.*属性值
-
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
-
jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
-
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
-
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
-
@Configuration注解类上的@PropertySource
-
通过SpringApplication.setDefaultProperties指定的默认属性
8.Spring Boot 自动配置原理
8.1自动配置原理:
-
Spring Boot启动的时候,加载主配置类,开启了自动配置功能@EnableAutoConfiguration,
-
@EnableAutoConfiguration的作用:
-
利用EnableAutoConfigurationImportSelector给容器中导入一些组件
-
可以查询selectImports()方法的内容;
-
Listconfigurations=getCandidateConfigurations(annotation Metadata,attributes);获取候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
public final class SpringFactoriesLoader { public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class); private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap(); private SpringFactoriesLoader() { }
3.扫描所有jar包类路径下 META-INF/spring.factories
4.把扫描到的这些文件的内容包装成properties对象
5.从properties中获取到EnableAutoCongratulation.class类(类名)对应的值,然后把他们添加在容器中
8.2.自动配置原理(细节)
1)@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的内容才生效
| @Conitional扩展注解 | 作用(判断是否满足当前指定条件) |
|---|---|
| @ConditionalOnJava | 系统的Java版本是否符合要求 |
| @ConditionalOnBean | 容器中存在指定Bean |
| @ConditionalOnMissingBean | 容器中不存在指定Bean |
| @ConditionalOnExpression | 满足SpEl表达式指定 |
| @ConditionalOnClass | 系统中有指定的类 |
| @ConditionalOnMissingClass | 系统中没有指定的类 |
| @ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
| @ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
| @ConditionalOnResource | 类路径下是否存在指定资源文件 |
| @ConditionalOnWebApplication | 当前是web环境 |
| @ConditionalOnNotWebApplication | 当前不是web环境 |
| @ConditionalOnJndi | JNDI存在指定项 |
自动配置类必须在一定条件下生效
在配置文件中编写
#开启SpringBoot的debug debug=true
我们可以通过启用debug=true属性;来让控制台打印自动生成报告,这样我们就可以很方便的知道哪些自动配置类生效
Positive matches: 自动配置类启用的
Negative matches: 未匹配到
三、Spring Boot 与日志
1、日志框架
市面上的日志框架
JUL , JCL , Jboss-logging , logback , log4j , log4j2 , slf4j
| 日志门面(日志抽象层) | 日志实现 |
|---|---|
| log4j、JUL(java.util.logging)、log4j2、logback |
左边选一个门面(抽象层)、右边来选一个实现
- Jboss 太复杂 JCL 最后一次更新在2014年
- SLF4j log4j logback出自同一人
- Log4j2 Apache公司的全新日志框架
日志门面:SLF4J;
日志实现:Logback > log4j
SpringBoot :底层是Spring框架,Spring框架默认使用是JCL
SpringBoot 选用SLF4j和logback
2、SLF4j使用
1)如何在系统中使用SLF4j
以后在开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,二傻调用日志抽象层里面的方法;
给系统里面导入slf4j的jar和logback的实现jar
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使用的情况

SELF4j关联了logback日志框架后的正确使用情况

调用SELF4j的接口,SELF4j调用底层日志的jar包

通过适配层将两者关联
2)遗留问题
for example:a情况(slf4j+logback):Spring (commons-logging)、Hibernate( jBOSS-logging)、Mybatis…
统一日志记录,即使 是别的框架,和我一起统一使用slf4j进行输出

-
将系统中其他日志框架先排出去
-
用中间包替换所有的日志框架
-
导入slf4j其他的实现
----------------------SpringBoot就是这么实现的
3)SpringBoot日志关系
-
使用logback记录日志
-
把其他日志转为slf4j
-
导入抽象层
-
中间替换包(偷梁换柱)
-
如果我们要引入其他框架,一定要把这个框架的默认日志依赖移除
3.日志使用
1)默认配置
SpringBoot 默认帮我们配置好了日志;
1 //记录器 2 org.slf4j.Logger logger= org.slf4j.LoggerFactory.getLogger(getClass()); 3 4 @Test 5 void contextLoads() { 6 //日志的级别 7 //由低到高 trace debug info warn error 8 //可以调整需要输出的日志级别,日志就只会在这个级别的更高级别生效 9 logger.trace("这是trance日志"); 10 logger.debug("这是debug日志"); 11 //SpringBoot 默认使用的是info级别,没有指定级别的就用SpringBoot默认规定的级别:root级别(info) 12 logger.info("这是info日志"); 13 logger.warn("这是warn日志"); 14 logger.error("这是error日志"); 15 }
SpringBoot修改日志默认配置
path和file都存在,file为主
1 logging.level.com.jirath=trace 2 #在当前磁盘下新建Spring和log文件夹:使用spring.log作为默认文件 3 logging.file.path=/spring/log 4 #不指定路径就在当前项目下生成日志 5 #logging.file.name=springboot.log 6 #可以指定完整路径 7 logging.file.name=E:/springboot.log 8 #在控制台输出的日志格式 9 logging.pattern.console================%n%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n 10 #指定文件中日志输出格式 11 logging.pattern.file=

SpringBoot 关于日志的其他默认设置:
位于spring-boot-2.2.0.RELEASE.jar!/org/springframework/boot/logging/logback/中,打开即为SpringBoot针对LogBack的配置封装。

其中,SpringBoot将默认级别(root)设置为了info
在配置文件中配置的属性会被一个名为LoggingApplicationListener(单击配置文件配置项即可查看)相似的类接收
LoggingApplicationListener同时与一个LoggingSystemProperties(在logback桶目录下)的类对应在这里获取输入的值,进行解析
在base.xml中SpringBoot针对控制台与文件输出有分别的定义,如图

在文件默认配置中,SpringBoot同时设置了文件在最大数值,当超出数值,日志就会自动分文件记录,如:log1,log2

2)指定配置
在实际使用时,同时会遇到其他功能的需求,自动归档等等等等,
要想使用自己的配置文件,Spring.io中在特性下有一章节专门讲述了SpringBoot配置默认日志的方法:在Spring目录中放logback.xml即可
给类路径下放上每个框架自己的配置文件即可:SpringBoot就不再使用默认配置

Spring Boot includes a number of extensions to Logback that can help with advanced configuration. You can use these extensions in your logback-spring.xml configuration file.
logback.xml:直接被日志框架识别
logback-spring.xml:日志就不直接加载日志配置项,由SpringBoot解析日志配置,就可以使用SpringBoot的高级Profile功能
<springProfile name="dev">
<!--可以指定某段配置只在某个环境下生效-->
</springProfile>
四、SpringBoot与Web开发
1、使用SpringBoot
-
创建SpringBoot应用,选中我们需要的模块;
-
SpringBoot已经默认将这些场景布置好,只需要在配置文件中指定少量配置就可以运行起来;
-
自己编写业务代码;
在这个场景中,SpringBoot帮我们配置
- XXXXAutoConfiguration:帮我们给容器中自动配置组件
- 在Spring-boot-autoconfigure中找到web模块
- 自动配置类在其中
- XXXProperties:配置类来封装配置文件的内容
2、SpringBoot对静态页面的映射规则
在WebMvcAutoConfiguration中
2.1 访问静态资源
第一种 导入的webjars
1 public void addResourceHandlers(ResourceHandlerRegistry registry) { 2 if (!this.resourceProperties.isAddMappings()) { 3 logger.debug("Default resource handling disabled"); 4 } else { 5 Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); 6 CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); 7 if (!registry.hasMappingForPattern("/webjars/**")) { 8 this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); 9 } 10 11 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); 12 if (!registry.hasMappingForPattern(staticPathPattern)) { 13 this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); 14 } 15 16 } 17 }
-
由上方代码,所有/webjars/**,下的请求都会去classpath:/META-INF/resources/webjars/中寻找资源
- webjars:以jar包的方式引入静态资源;
- webJars
- 将常用的前端框架给了一个Maven依赖的方式
- 选好要使用的版本,在pom文件中引入即可
- 引入后在jar包中,设置中显示隐藏文件夹即可打开,符合映射规则
-
代码中同时设置了缓存时间,缓存时间可以在resourceProperties中设置
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
@ConfigurationProperties( prefix = "spring.resources", ignoreUnknownFields = false ) public class ResourceProperties { //可以设置与静态资源有关的参数,缓存时间
第二种"/**"访问当前项目的任何资源
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)); }
进入getResoutceLocations
static String[] getResourceLocations(String[] staticLocations) { String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length]; System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length); System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length); return locations; }
查看代码是从其他方法中引入了参数(与1版本不同)
返回查看参数的来源
getStaticLocations
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
总结
"/**"访问当前项目的任何资源(静态资源文件夹)都会在下方的文件夹中找内容
- “classpath:/META-INF/resources/”,
- “classpath:/resources/”,非默认的resources,而是新建的resources文件夹
- “classpath:/static/”
- “classpath:/public/”,(默认无,需要新建)
- “/”:当前项目的路径
2.2 欢迎页配置
1 @Bean 2 public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { 3 WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern()); 4 welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider)); 5 return welcomePageHandlerMapping; 6 }
1 private Optional<Resource> getWelcomePage() { 2 String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations()); 3 return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst(); 4 } 5 private Resource getIndexHtml(String location) { 6 return this.resourceLoader.getResource(location + "index.html"); 7 }
静态资源文件夹下所有index.html页面:被"/**"映射
2.3 图标
所有的**/favicon.ico都是在静态资源环境下找;
同时静态资源的位置是可以改变的
spring.resources.static-location=位置
3、模板引擎
之前多使用jsp页面,可以很方便的嵌入数据等,但SpringBoot 使用嵌入式的tomcat,不支持jsp页面,只能支持HTML,
JSP、Velocity、Freemarker、Thymeleaf;
模板引擎的作用:在写页面时,将一些数据与渲染数据的模板结合输出,JSP与其他的模板引擎都是这一原理
SpringBoot推荐的Thymeleaf;
语法更简单,功能更强大;
引入thymeleaf
- ````xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> ```` - 详情见SpringBoot官网文档 - 布局功能的支持程序 thymeleaf3主程序 layout2以上版本
Thymeleaf使用&语法
1 - 在AutoConf...中有配置类,打开properties有默认自动配置项 2 3 - ````java 4 private static final Charset DEFAULT_ENCODING; 5 public static final String DEFAULT_PREFIX = "classpath:/templates/"; 6 public static final String DEFAULT_SUFFIX = ".html"; 7 private boolean checkTemplate = true; 8 private boolean checkTemplateLocation = true; 9 private String prefix = "classpath:/templates/"; 10 private String suffix = ".html"; 11 private String mode = "HTML"; 12 private Charset encoding; 13 private boolean cache; 14 private Integer templateResolverOrder; 15 private String[] viewNames; 16 private String[] excludedViewNames; 17 private boolean enableSpringElCompiler; 18 private boolean renderHiddenMarkersBeforeCheckboxes; 19 private boolean enabled; 20 private final ThymeleafProperties.Servlet servlet; 21 private final ThymeleafProperties.Reactive reactive; 22 //只要我们把HTML文件放在classpath:/templates/,thymeleaf就能自动渲染 23 //同时可以在配置文件中修改配置 24 ```` 25 26 - [thymeleaf官网](https://www.thymeleaf.org/) 27 28 -  29 30 - 现代化java服务端的模板引擎 31 32 -  33 34 - 使用 35 36 ````ht 37 导入开启thymeleaf的语法空间,开启语法提示 38 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 39 ```` 40 41 ````java 42 @RequestMapping("/html") 43 public String testHtml(Map<String,Object> map){ 44 map.put("hello", "这是Controller中返回的话"); 45 return "testPage"; 46 } 47 ````
1 ````html 2 <!DOCTYPE html> 3 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>test</title> 7 </head> 8 <body> 9 <h1>这是一个测试文字</h1> 10 <!--将div里面的文本内容设置为,可以替换静态的信息--> 11 <div th:text="${hello}">这是静态的语句</div> 12 </body> 13 </html> 14 ````
语法规则
使用${AttributeName}取值
1)、th:text 改变当前元素里面的内容
th:任意html属性 替换原生属性的值

2)表达式
Variable Expressions: ${…} 获取变量值,OGNL;
获取对象的属性、调用方法
- 使用内置的基本对象内置的一些工具对象
- #ctx : the context object.
- #vars: the context variables.
- #locale : the context locale.
- #request : (only in Web Contexts) the HttpServletRequest object.
- #response : (only in Web Contexts) the HttpServletResponse object.
- #session : (only in Web Contexts) the HttpSession object.
- #servletContext : (only in Web Contexts) the ServletContext object.
Established locale country: <span th:text="${#locale.country}">US</span>.
- 内置的一些工具对象
- #execInfo : information about the template being processed.
- #messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
- #uris : methods for escaping parts of URLs/URIs
- #conversions : methods for executing the configured conversion service (if any).
- #dates : methods for java.util.Date objects: formatting, component extraction, etc.
- #calendars : analogous to
- #dates , but for java.util.Calendar objects. #numbers : methods for formatting numeric objects.
- #strings : methods for String objects: contains, startsWith, prepending/appending, etc.
- #objects : methods for objects in general.
- #bools : methods for boolean evaluation.
- #arrays : methods for arrays.
- #lists : methods for lists. #sets : methods for sets. #maps : methods for maps.
- #aggregates : methods for creating aggregates on arrays or collections.
- #ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
- Selection Variable Expressions: *{…} 变量的选择表达式,与${}在性质上是一样的,补充:配合th:object 使用
Message Expressions: #{…} 获取国际化内容
Link URL Expressions: @{…} 定义URL链接
Fragment Expressions: ~{…} 插入文档
Literals(字面量)
- Text literals: ‘one text’ , ‘Another one!’ ,…
- Number literals: 0 , 34 , 3.0 , 12.3 ,…
- Boolean literals: true , false
- Null literal: null
- Literal tokens: one , sometext , main ,…
Text operations: (文本操作)
- String concatenation: +
- Literal substitutions: |The name is ${name}|
Arithmetic operations: (数学运算)
- Binary operators: + , - , * , / , %
- Minus sign (unary operator):
Boolean operations: (布尔运算)
- Binary operators: and , or
- Boolean negation (unary operator): ! , not
Comparisons and equality:(比较运算)
- Comparators: > , < , >= , <= ( gt , lt , ge , le )
- Equality operators: == , != ( eq , ne )
Conditional operators:(条件运算)(三元运算符也支持)
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- Default: (value) ?: (defaultvalue)
Special tokens:(特殊)
- No-Operation: _ 不做处理
1 OGNL的例子 2 /* * Access to properties using the point (.). Equivalent to calling property getters. */ 3 ${person.father.name} 4 /* * Access to properties can also be made by using brackets ([]) and writing * the name of the property as a variable or between single quotes. */ 5 ${person['father']['name']} 6 /* * If the object is a map, both dot and bracket syntax will be equivalent to * executing a call on its get(...) method. */ ${countriesByCode.ES} ${personsByName['Stephen Zucchini'].age} 7 /* * Indexed access to arrays or collections is also performed with brackets, * writing the index without quotes. */ ${personsArray[0].name} 8 /* * Methods can be called, even with arguments. */ ${person.createCompleteName()} ${person.createCompleteNameWithSeparator('-')}
转载自:https://blog.csdn.net/weixin_44494373/article/details/104566898



浙公网安备 33010602011771号