文章目录
- 参考资料
- 运行环境
- 1. SpringBoot概述
- 1.1 Spring 缺点
- 1.2 SpringBoot功能
- 1.3 小结
- 2. SpringBoot 快速入门
- 2.1 使用案例
- 2.2 实现步骤
- 2.3 使用 IDEA2021 快速创建SpringBoot项目
- 2.3 小结
- 3. SpringBoot 起步依赖原理分析
- 4. SpringBoot配置
- 4.1 配置文件分类
- 4.2 yaml
- 基本语法
- YAML : 数据格式
- YAML: 参数引用
- YAML: 小结
- 4.3 读取配置文件内容
- 4.3.1 @Value
- 4.3.2 Environment
- 4.3.3 @ConfigurationProperties
- 4.4 profile
- 4.4.1 多profile文件配置
- 4.4.2 yml多文档方式
- 4.4.3 通过JVM虚拟机配置激活yml文档
- 4.4.4 通过progarming参数激活yml文档
- 4.4.5 通过命令行在执行jar包时激活yml文档
- 4.4.6 总结
- 4.5 内部配置加载顺序
- 4.6 外部配置加载顺序
- 5. 总结
参考资料
运行环境
- IDEA
- JDK8
- SpringBoot 2.6.2
1. SpringBoot概述
1.1 Spring 缺点
- 配置繁琐
spring2.5 基于注解的组件扫描, 消除了大量针对应用程序自身组件显示的XML配置
spring3.0 引入了基于Java的配置、类型安全的可重构配置方式,可代替XML - 依赖繁琐
在环境搭建时,需分析要导入哪些库的坐标,而且还要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。
1.2 SpringBoot功能
- 自动配置
Spring Boot的自动配置是一个运行时(即应用程序启动时)的过程,考虑了众多因素才决定Spring配置应该用哪个,不该用哪个,该过程是SpringBoot自动完成的。 - 起步依赖
本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,整合后可支持某项功能。
简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。 - 辅助功能
提供了一些大型项目中常见的非功能性特性,如嵌入式服务器,安全、指标、健康检测、外部配置等。
Spring Boot 并不是对 Spring功能上的增强, 而是提供了一种 快速使用 Spring的方式。
1.3 小结
SpringBoot提供了一种快速开发Spring项目的方式,并非是对Spring功能上的增强。
Spring的缺点:
- 配置繁琐
- 依赖繁琐
2. SpringBoot 快速入门
2.1 使用案例
需求: 搭建SpringBoot工程,定义helloController.hello()方法,返回 “Hello SpringBoot!”
注意
:@SpringBootApplication标记的类必须在其他所有类的外层,否则启动会报错
2.2 实现步骤
- 创建Maven项目
- 导入SpringBoot起步依赖
pom.xml
<?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>
<groupId>org.example</groupId>
<artifactId>Demo01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- SpringBoot工程需要继承的父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
</parent>
<dependencies>
<!-- web 开发的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
- 定义Controller
hello.java
package com.uni.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class hello {
@RequestMapping("/hello")
public String hello(){
return "hello,SpringBoot!";
}
}
- 编写引导类
HelloApplication.java
package com.uni;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
- 启动测试,访问
localhost:8080/hello
2.3 使用 IDEA2021 快速创建SpringBoot项目
选择 SpringWeb
标记项目的src/main下的java文件夹为 source(蓝色的文件夹),否则无法正常运行包下的Java类
IDEA自动生成的pom依赖
pom.xml
<?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.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.uni</groupId>
<artifactId>demo02</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo02</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.3 小结
- SpringBoot 在创建项目时,使用jar的打包方式
- SpringBoot的引导类是项目入口,运行main方法就可以启动项目
- 使用SpringBoot和Spring构建的项目,业务代码编写方式完全一样
3. SpringBoot 起步依赖原理分析
spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本
在各种stater中,定义了完成该功能需要的坐标合计,其中大部分版本信息来自于父工程
工程继承parent,引入starter后,通过依赖传递,可以简单方便的获得需要的jar包,且不会存在版本冲突等问题。
4. SpringBoot配置
4.1 配置文件分类
SpringBoot是基于约定的,很多配置都有默认值,但若想使用自己的配置替换默认,可使用application.properties或者application.yml (/.yaml) 进行配置
- properties
server.prot=8080
- yml
server:
port: 8080
在同一级目录下优先级(高 -> 低)为 properties -> yml -> yaml
4.2 yaml
yaml 全称是 yaml ain’t Markup Language 。 YAML是一种直观的能够被电脑识别的数据序列化格式,并且容器被人类阅读,容易和脚本语言交互,可被支持YAML库的不同的编程语言程序导入,比如:C/C++、Ruby、Python、Java、Perl等。
YML文件是以数据为核心的,比传统的XML方式更简洁, YAML文件的扩展名可用.yml或.yaml
- properties
server.port=8080
server.address=127.0.0.1
- xml
<server>
<port>8080</port>
<address>127.0.0.1</address>
</server>
- yml
server:
port: 8080
address: 127.0.0.1
基本语法
- 大小写敏感
- 数据值前边必须有空格,作为分隔符
- 使用缩进表示层级关系
- 缩进时
不允许
使用Tab键,只需用使用空格(各个系统Tab对应的空格数目可能不同,导致层次混乱) - 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
-
#
表示注释,从这个字符已知到行尾,都会被解析器忽略
YAML : 数据格式
- 对象(map): 键值对的集合
person:
name: uni
# 行内写法
person: {name: uni}
- 数组:一组按次序排列的值
address:
- hangzhou
- wenzhou
# 行内写法
address: [hangzhou, wenzhou]
- 纯量: 单个的、不可再分的值
msg1: 'hello \n world' # 单引忽略转义字符
msg2: "hello \n world" # 双引识别转义字符
YAML: 参数引用
name : uni
person:
name: ${name} # 引用上面定义的name值
YAML: 小结
配置文件类型
- properties : 和以前一样
- yml / yaml : 注意空格
yaml: 简洁、以数据为核心
- 基本语法
- 大小写敏感
- 数值前必须有空格作为分隔符
- 使用空格缩进表示层级关系,相同缩进表示同一级
- 数据格式
- 对象
- 数组:使用"-" 表示数组每个元素
- 参数引用
${key}
4.3 读取配置文件内容
4.3.1 @Value
application.yml
name: uni
student:
name: cc
address:
- hangzhou
- wenzhou
HelloController.java
package com.uni.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${name}")
private String name_uni;
@Value("${student.name}")
private String name_stu;
@Value("${address[0]}")
private String addr;
@RequestMapping("/hello")
public void hello(){
System.out.println("hello, I'm " + name_uni);
System.out.println("I'm " + name_stu);
System.out.println("城市: " + addr);
}
}
4.3.2 Environment
用和之前相同的yml文件
HelloController.java
package com.uni.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private Environment env;
@RequestMapping("/hello")
public void hello(){
System.out.println("hello, I'm " + env.getProperty("name"));
System.out.println("I'm " + env.getProperty("student.name"));
System.out.println("城市: " + env.getProperty("address[0]"));
}
}
4.3.3 @ConfigurationProperties
此注解一个于标记某个类表示支持赋值配置文件里的内容
案例: 标记Student实体类
Student.java
package com.uni;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
private String name;
private int age;
private String[] hobbys;
}
spring-boot的配置 application.yml
student:
name: cc
age: 21
hobbys:
- 跑步
- 睡觉
HelloController.java
package com.uni.controller;
import com.uni.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private Student student;
@RequestMapping("/stu")
public void stu(){
System.out.println(student);
}
}
启动application,访问 lcoalhost:8080/stu
,终端的结果为:
Student(name=cc, age=21, hobbys=[跑步, 睡觉])
4.4 profile
作用:动态配置切换,解决Spring Boot应用开发,开发、测试、生产等不同环境下的配置切换问题
需要了解的内容:
- profile 配置方式
- 多profile文件方式
- yml多文档方式
- profile激活方式
- 配置文件
- 虚拟机参数
- 命令行参数
4.4.1 多profile文件配置
4.4.2 yml多文档方式
在application.yml
配置文件中以三个横岗— 划分一个文档区域,比如:
---
server:
port: 8081
---
案例:在一个yml文件中设置3个启动端口,并激活其中的1个服务器端口
application.yml
---
server:
port: 8081
spring:
config:
activate:
on-profile: dev
---
server:
port: 8082
spring:
config:
activate:
on-profile: test
---
server:
port: 8083
spring:
config:
activate:
on-profile: pro
---
spring:
profiles:
active: test
4.4.3 通过JVM虚拟机配置激活yml文档
在IDEA设置Run/Debug Configurations
中的 vm options
参数
范例:激活yml里的test文档
-Dspring.profiles.active=test
其中test是yml里通过三个横杠设置的一个文档配置,如下:
---
server:
port: 8082
spring:
config:
activate:
on-profile: test
---
4.4.4 通过progarming参数激活yml文档
在IDEA设置Run/Debug Configurations
中的 programming options
参数
范例:
--spring.profiles.active=test
4.4.5 通过命令行在执行jar包时激活yml文档
java -jar 打包后的.jar --spring.profiles.active=test
4.4.6 总结
- profile是用来完成不同环境下,配置动态切换功能的
- profile配置方式
- 多profile文件方式:提供多个配置文件,每个代表一种环境
- application-dev.properties/yml 开发环境
- application-test.properties/yml 测试环境
- application-pro.properties/yml 生产环境
- yml多文档方式
- 在yml中使用 使用三个横杠— 分割不同配置
- profile激活方式
- 配置文件:在yml配置文件中
spring.profiles.active=dev
- 虚拟机参数: 在VM opionts指定
-Dspring.profiles.active=dev
- 命令行参数:
java -jar xxx.jar --spring.profiles.active=dev
4.5 内部配置加载顺序
Springboot程序启动时,会从以下位置加载配置文件:
- file: ./config/ : 当前目录下的/config目录下
- file:./ : 当前项目的根目录
- classpath:/config/: classpath的/config目录
- classpath: / classpath的根目录
加载顺序为上文的排列顺序,高优先级配置的属性会生效
4.6 外部配置加载顺序
通过官网查看外部属性加载顺序
1. Default properties (specified by setting `SpringApplication.setDefaultProperties`).
2. [`@PropertySource`](https://docs.spring.io/spring-framework/docs/5.3.14/javadoc-api/org/springframework/context/annotation/PropertySource.html) annotations on your `@Configuration` classes. Please note that such property sources are not added to the `Environment` until the application context is being refreshed. This is too late to configure certain properties such as `logging.*` and `spring.main.*` which are read before refresh begins.
3. Config data (such as `application.properties` files).
4. A `RandomValuePropertySource` that has properties only in `random.*`.
5. OS environment variables.
6. Java System properties (`System.getProperties()`).
7. JNDI attributes from `java:comp/env`.
8. `ServletContext` init parameters.
9. `ServletConfig` init parameters.
10. Properties from `SPRING_APPLICATION_JSON` (inline JSON embedded in an environment variable or system property).
11. Command line arguments.
12. `properties` attribute on your tests. Available on [`@SpringBootTest`]
(https://docs.spring.io/spring-boot/docs/2.6.2/api/org/springframework/boot/test/context/SpringBootTest.html) and the [test annotations for testing a particular slice of your application](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#features.testing.spring-boot-applications.autoconfigured-tests).
13. [`@TestPropertySource`](https://docs.spring.io/spring-framework/docs/5.3.14/javadoc-api/org/springframework/test/context/TestPropertySource.html) annotations on your tests.
14. [Devtools global settings properties](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#using.devtools.globalsettings) in the `$HOME/.config/spring-boot` directory when devtools is active.
Config data files are considered in the following order:
1. [Application properties](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#features.external-config.files) packaged inside your jar (`application.properties` and YAML variants).
2. [Profile-specific application properties](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#features.external-config.files.profile-specific) packaged inside your jar (`application-{profile}.properties` and YAML variants).
3. [Application properties](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#features.external-config.files) outside of your packaged jar (`application.properties` and YAML variants).
4. [Profile-specific application properties](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#features.external-config.files.profile-specific) outside of your packaged jar (`application-{profile}.properties` and YAML variants).
其中第十一种,在执行jar包时通过命令行指定
java -jar xxx.jar --server.port=8082
官网7.2.3 的example
$ java -jar myproject.jar --spring.config.location=\
optional:classpath:/default.properties,\
optional:classpath:/override.properties
最常用的还是在jar包的同级目录下创建application.properties
,比它优先级更高的是同级目录的config文件夹里的properties
可用于修改jar包内部一些配置,而且不影响项目其他的配置,特别方便
5. 总结
通过本次的学习,快速入门了 SpringBoot Web,简单的实现了 HelloWorld,同样是Web开发,跟之前的 Tomcat 部署相比,SpringBootWeb方便许多,只需要执行一个带有@SpringBootApplication注解的类,而且调用了SpringbootTestApplication方法就能启动一个web程序,而且不用配置web.xml
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootTestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootTestApplication.class, args);
}
}
除此之外,笔者第一次接触了yml、yaml、propertries多种配置文件混合使用的情况,它们之间的优先级是 p > yml > yaml
通过Srping的注解方式简写了一个Controller层的类,之前都是继承一个HttpServlet然后使用@WebServlet进行编写,现在感觉方便很多,因为可以在同一个类里写多个方法用于响应不同地址的请求。
@RestController
public class hello {
@RequestMapping("/hello")
public String hello(){
return "hello,SpringBoot!";
}
}
起步依赖的部分有一点蒙,这应该属于Maven的知识,笔者没有系统学过Maven,现在暂时的理解就是它能像Java类一样去继承一个父类,然后Maven也可以实现这种继承,所以新建的SpringBootWeb项目里的pom.xml看起来较为简洁,其原因大概就是继承了封装好的一个Maven依赖,然后SpringBoot已经设计好了所有的依赖,现在可以直接使用。
综合以上,SpringBoot的使用并不复杂,但是对于其原理的理解则还需要进一步深入,同时需要花更多时间来熟练应用。