文章目录
一、配置文件相关
1.1 配置文件的优先级
按照配置后缀优先级如下(没有算bootstrap,由高到低)
-
properties:传统格式/默认格式
-
yml:主流格式
-
yaml:多认为yml为yaml缩写
按照路径优先级(由高到低)
文件路径,运行环境(打包后的文件):
- file: config/application.yml(运维组长)
- file: application.yml(运维)
类路径下,开发阶段使用:
- classpath: config/application.yml(项目经理)
- classpath: application.yml (程序员)
1.2 从配置文件读取数据
yml语法规则如下:
类型 | 说明 |
---|---|
boolean: true | True,true,TRUE,FALSE,false,False均可以 |
float: 3.14 | 支持科学计数法,6.8353e+5 |
int: 114 | 支持二进制、八进制、十六进制 |
null: ~ | 用null表示 |
string: helloworld | 可直接书写字符串 |
string: “Hello World” | 可以用双引号,它可以用来表示转义字符 |
datatime: 2023-9-25T20:38+8:00 | 时间与日期之间用T连接,同时+后面表示时区 |
array: [1,2,3,4] | 可以表示数组 |
object: [{name: yjx23332,score: 60},{name: zhangshan,score: 60}] | 可以表示对象数组 |
同时还支持另外一种写法
# 数组
subject:
- Java
- Python
- C++
# 对象
user:
name: yjx23332
score: 60
hobbies:
- game
- book
- music
# 对象数组 一
users:
- name: yjx23332
score: 60
hobbies:
- game
- book
- music
- name: lisi
score: 70
hobbies:
- sports
- dance
# 对象数组 二
users:
-
name: yjx23332
score: 60
hobbies:
- game
- book
- music
-
name: lisi
score: 70
hobbies:
- sports
- dance
同时如下,可以在配置文件中引入变量
${users[0].name}
地址格式
windowdsaddress: C:/Users/Public
linuxaddress: /usr/data
<?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>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.3</version>
</parent>
<groupId>org.example</groupId>
<artifactId>test</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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
package com.yjx23332;
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);
}
}
server:
port: 80
a:
b:
c:
d: 12312
hobbies: [game,read,music]
hobbies2:
- game
- read
- music
hobbies3: game,read,music
user:
username: yjx23332
hobby: ${hobbies2[1]}
1.2.1 一个个获取
package com.yjx23332.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class testcontroller {
@Value("${a.b.c.d}")
String part;
@Value("${hobbies[0]}")
String hobby;
@Value("${hobbies2[0]}")
String hobby2;
//通过 # 号,我们可以加入代码操作,来处理
@Value("#{'${hobbies3}'.split(',')}")
String[] hobbies3;
@Value("${user.hobby}")
String userHobby;
@RequestMapping
public String test(){
System.out.println(part);
System.out.println(hobby);
System.out.println(hobby2);
System.out.println(hobbies3[0]);
System.out.println(name);
System.out.println(userHobby);
return "";
}
}
注意
- 如果以name为未命名方式,(name: yjx23332)文字+数字的混合,它会过滤掉数字。因此改为了username,可能是一些默认规则。
- 以0开头的数字可能会被认为是其他进制
1.2.2 一次性读取
package com.yjx23332.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class testcontroller {
@Autowired
Environment environment;
@RequestMapping
public String test(){
System.out.println(environment.getProperty("hobbies[0]"));
return "";
}
}
1.2.3 封装读取
读取复杂数据时,我们需要配置相关的信息,否则不能直接使用。比如直接读出数组,或者自定义的对象等。
我们尝试读出User类
package com.yjx23332.entity;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "user")
public class User {
private String username;
private String hobby;
}
package com.yjx23332.controller;
import com.yjx23332.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/test")
public class testcontroller {
@Resource
private User user;
@RequestMapping
public String test(){
System.out.println(user.toString());
return "";
}
}
1.3 多环境开发
# 使用哪一套,公共配置
spring:
profiles:
active: pro
# 环境配置
---
# 生产环境
spring:
profiles: pro
server:
port: 80
---
# 开发环境
spring:
profiles: dev
server:
port: 81
---
# 测试环境
spring:
profiles: test
server:
port: 92
不过,我们通常会将他们分为多个文件
在公共类直接写用那一套即可
spring:
profiles:
active: pro
1.3.1 分组管理环境
我们可以依据配置的内容,再次细分
spring:
profiles:
active: dev
include: devMVC,devRedis
后面的配置会覆盖前面相同的配置。
active是最后加载的,也就是,dev会覆盖前面相同的配置。
如下使用分组模式,dev会启动dev相关组,pro会启动pro相关组
spring:
profiles:
active: dev
group:
"dev": devMVC,devRedis
"pro": proRedis,proMVC
1.3.2 maven分组管理
我们把激活的环境修改为如下
# 使用哪一套
spring:
profiles:
active: @profile.active@
group:
"dev": devMVC,devRedis
"pro": proRedis,proMVC
<profiles>
<profile>
<id>env_pro</id>
<properties>
<!--设置其值-->
<profile.active>pro</profile.active>
</properties>
<!-- 默认使用,它标注的就是maven使用的环境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>env_test</id>
<properties>
<!--设置其值-->
<profile.active>test</profile.active>
</properties>
</profile>
<profile>
<id>env_dev</id>
<properties>
<!--设置其值-->
<profile.active>dev</profile.active>
</properties>
</profile>
</profiles>
如果在切换时,不生效。可以尝试
clean->compile
1.4 临时属性
在使用Spring Boot 打包的jar包的时候,我们可以通过临时属性去修改yml里面的配置。
test.jar 是我们打好的jar包
格式就是在properties配置方法基础上,加上--。
因为命令行传输参数优先级更高。
java -jar test.jar --server.port=8080
参考官方文档,配置的加载顺序Externalized Configuration
优先级由低到高
我们传入的参数,其实就是下面的 args
如果不希望临时参数,我们不传入args即可
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class,args);
}
}
当然,临时属性也可以在IDEA里面在Program argument进行配置。
二、JUnit
2.1 基本使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
这边的结构要尽量一致,因为他会进行一个定位。
- 当前的测试类在对应主程序位置在,引导类的包或者子包下,就不需要修改任何东西。
下图test测试类,和引导类MainApplication在同一包下因此没有问题
package com.yjx23332;
import com.yjx23332.entity.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class test {
@Autowired
private User user;
@Test
void test1(){
System.out.println(user);
}
}
2.2 解决测试类不在引导类下
显示的标识引导类
@SpringBootTest(classes = MainApplication.class)
@RunWith(SpringRunner.class)
public class test {
@Autowired
private User user;
@Test
void test1(){
System.out.println(user);
}
}
也可以写成这样
@SpringBootTest
@ContextConfiguration(classes = MainApplication.class)
public class test {
@Autowired
private User user;
@Test
void test1(){
System.out.println(user);
}
}
三、日志基础操作
3.1 日志作用
- 编程期调试代码
- 运营期记录信息
- 记录日常运营重要信息(峰值流量、平均响应时长等)
- 记录应用报错信息(报错堆栈)
- 记录运维过程数据(扩容、宕机、报警等)
3.2 日志级别
TRACE、DEBUG 、INFO、WARN、ERROR 、FATAL
通常用四种,由高到低
- error:上线后看的
- warn
- info
- debug:开发看的时候
使用只需要如下即可
private static Logger log = LoggerFactory.getLogger(当前类.class);
笔者这里导入的lombok,可以帮助我们创建Log,因此可以直接使用,我们也可以自己实现
继承如下代码即可。
public class BaseClass{
private Class clazz;
private static Logger log;
public BaseClass(){
clazz = this.getClass();
log = LoggerFactory.getLogger(clazz);
}
}
我们首先输出一下
package com.yjx23332.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
@Slf4j
public class testcontroller {
@RequestMapping
public void test(){
log.debug("debug...");
log.info("info...");
log.warn("warn...");
log.error("error...");
}
}
如图可知,一般启动默认最低是info
我们需要手动调低它至debug,可以用临时属性,但我们此处在yml设置即可
开启debug级别
debug: true
但是仍然看不到debug输出
另外,我们使用的最多的是
logging:
level: # 级别
# 当前项目根目录下,为debug模式
root: debug
这里我们看得到debug的输出了
3.3 日志输出规则
设置包的级别
logging:
level: # 级别
root: info
com.yjx23332.controller: debug
设置分组的级别
logging:
group:
testLog: com.yjx23332.controller,com.fasterxml.jackson
level: # 级别
root: info
testLog: debug
3.4 输出格式
时间-级别-PID-所属线程-所属类/接口名
SpringBoot会在所属类/接口名的报名过长时,将其简化或者直接删除
设置日志格式
logging:
pattern:
# %d时间 %m/%msg/%message消息 %n换行
console: "%d - %m %p %n"
logging:
pattern:
# %5m 代表占位5,用于对其格式
console: "%d - %5m %p %n"
logging:
pattern:
# %clr(%5m) 使用颜色,颜色是默认的集中颜色
console: "%d - %5m %clr(%p) %n"
logging:
pattern:
# %t线程,%c类名. %-40.40c 左对齐(与C语言一致),截取.40指的是当内容超出时,截取内容40位
console: "%d %clr(%5p) --- [%16t] %-40.40c : %m %n"
logging:
pattern:
# 使用cyan颜色(需要系统中有的)
console: "%d %clr(%5p) --- [%16t] %clr(%-40.40c){cyan} : %m %n"
3.5 文件记录日志
如下就会创建一个server.log文件,在目录下(IDEA里面看不到)。当日志数目到达一定的量时,才会写入。
logging:
file:
name: server.log
我们通常不会将所有日志写入一个文件内,我们可以按天、按报错内容、报错类来记录
logging:
logback:
rollingpolicy:
# 最大大小,超过换新的
max-file-size: 4KB
# server.2020-01-01.0.log,%d是日期,%i是当日第几个
#也可以指定日期 %d{yyyy-MM-dd}
file-name-pattern: server.%d%i.log
通常我们也不会写在yml内,通常会用一个文件夹logback.xml记录上述内容。
具体的配置可以去网上搜,有很多。
logging:
config: classpath:logback.xml