本文内容来自Spring Boot相关书籍学习总结
1、系统配置文件
1.1 application.properties
Spring Boot支持两种不同格式的配置文件:一种是Properties,另一种是YML。Spring Boot默认使用application.properties作为系统配置文件。
该文件包含Spring Boot项目的全局配置。我们可以在application.properties文件中配置Spring Boot支持的所有配置项,比如端口号、数据库连接、日志等。
1、基本语法
# 服务器端口配置
server.port=8081
2、配置文件加载顺序
Spring Boot系统启动时会按顺序依次读取4个不同路径下的配置文件:
1)项目根目录下的config目录。
2)项目根目录。
3)classpath下的config目录。
4)classpath目录。
注:一般在项目中习惯将配置文件放置在resources目录下。
3、修改默认配置文件名
通过修改项目启动类,调用SpringApplicationBuilder类的properties()方法可以实现自定义配置文件名称:
public static void main(String[] args) {
// SpringApplication.run(MyApplication.class, args);
new SpringApplicationBuilder(MyApplication.class)
.properties("spring.config.location=classpath:/mytest.properties")
.run(args);
}
Spring Boot项目启动加载时会默认读取更改名称的配置文件。
4、特殊数据类型注入
除了单个数值注入,properties文件还支持数组(列表)、Map类型的注入:
# list配置
user-list=aa,bb,cc,dd,ee
# Map配置
user-info={'name':'wang', 'age':'1', 'gender':'male'}
# list配置—引用类型
user-info-list[0].name=xx
user-info-list[0].age=12
user-info-list[1].name=ff
user-info-list[1].age=13
注入到类的对应属性:
@Value("#{'${app.user-name-list}'.split(',')}")
private List<String> userNameList;
@Value("#{${app.user-map}}")
private Map<String, String> userMap;
注入到类的List引用属性:
@Data
@Configuration
@ConfigurationProperties(prefix = "app")
public class UserConfig {
private List<User> userInfoList;
}
1.2 application.yml
application.yml是以yml为后缀,使用YAML(YAML Ain't a Markup Language)的配置文件。
1、基本语法
YML基本语法为key:(空格)value的键值对形式,冒号后面必须加上空格。通过空格的缩进来控制属性的层级关系,只要是左对齐的一列数据,都是同一个层级的。具体格式如下:
# 日志配置
logging:
level:
root: warn
file:
max-history: 30
max-size: 10MB
path: /var/log
YML文件虽然格式简洁直观,但是对格式要求较高,使用YML配置文件时需要注意以下几点:
1)属性值和冒号中间必须有空格,如name: Weiz正确,使用name:Weiz就会报错。
2)需要注意各属性之间的缩进和对齐。
3)缩进不允许使用tab,只允许空格。
4)属性和值区分字母大小写。
2、特殊数据类型注入
(1)普通的值(数字、字符串、布尔值)
可以使用双引号("")来转义字符串中的特殊字符
name: "zhangsan \n lisi"
(2)对象、Map(属性和值)
对象同样是以k:v的键值对方式展现的
person:
lastName: zhangsan
age: 20
如果使用行内写法,可以将对象的属性和值写成JSON格式,具体写法如下:
person: {lastName: zhangsan,age: 20}
(3)数组(List、Set)
数组是以- value的形式表示数组中的元素的,具体写法如下:
persons:
- zhangsan
- lisi
- wangwu
可以采用行内写法,数组使用中括号的形式,具体写法如下:
persons: [zhangsan, lisi, wangwu]
1.3 Properties与YML配置文件的区别
1)YML文件以数据为中心,对于数据的支持和展现非常友好。
2)Properties文件对格式的要求没那么严格,而YML文件以空格的缩进来控制层级关系,对格式的要求比较高,缩进格式不对时容易出错。
3)Properties文件支持@PropertySource注解,而YML文件不支持。
4)YML文件支持多文档块的使用方式,使用起来非常灵活。
5)Properties配置的优先级高于YML文件。因为YML文件的加载顺序先于Properties文件,如果两个文件存在相同的配置,后面加载的Properties中的配置会覆盖前面YML中的配置。
2、自定义配置项
Spring Boot提供了@Value注解、@ConfigurationProperties注解和Environment接口等3种方式自定义配置项。
2.1 @Value
Spring Boot提供@Value注解来设置简单的配置项,默认读取application.properties文件中的配置属性。
注意:
1)使用@Value注解时,所在类必须被Spring容器管理
2)@Value需要传入完整的配置项的Key值。
3)@Value注解默认读取application.properties配置文件,如果需要使用其他的配置文件,可以通过@PropertySource注解指定对应的配置文件。
2.2 Environment
Environment是Spring为运行环境提供的高度抽象的接口,它会自动获取系统加载的全部配置项,包括命令行参数,系统属性,系统环境,随机数,配置文件等。使用时无须其他的额外配置,只要在使用的类中注入Environment即可。
演示:
添加配置项:
app.username=mimang
读取配置项
@Autowired
private Environment env;
@Test
public void getProp() {
System.out.println(env.getProperty("app.username"));
}
注意:
1)使用Environment无须指定配置文件,其获取的是系统加载的全部配置文件中的配置项。
2)需要注意配置文件的编码格式,默认为ISO8859-1。
2.3 @ConfigurationProperties
使用注解@ConfigurationProperties将配置项和实体Bean关联起来,实现配置项和实体类字段的关联,读取配置文件数据。
添加配置文件mytest.properties
app.username=迷茫
app.password=123456
app.age=12
将配置文件中的配置项注入到自定义配置对象类
@Data
@Configuration
@ConfigurationProperties(prefix = "app")
@PropertySource(value = "classpath:mytest.properties", encoding = "UTF-8")
public class UserConfig {
private String username;
private String password;
private Integer age;
}
3、其他配置
3.1 随机数
Spring Boot支持在系统加载时配置随机数,使用${random}可以生成各种不同类型的随机值。Spring Boot提供的RandomValuePropertySource配置类可以很方便地生成随机数,可以生成integer、long、uuids和string类型的数据。
演示:
添加随机数配置项:
# 随机字符串
cfg.random.value=${random.value}
# uuid
cfg.random.uuid=${random.uuid}
# 随机int
cfg.random.number=${random.int}
# 随机long
cfg.random.bignumber=${random.long}
# 10以内的随机数
cfg.random.test1=${random.int(10)}
# 10-20的随机数
cfg.random.test2=${random.int[10,20]}
读取随机数配置项:
@Data
@Component
public class ConfigRandomValue {
@Value("${cfg.random.value}")
private String secret;
@Value("${cfg.random.number}")
private int number;
@Value("${cfg.random.bignumber}")
private long bigNumber;
@Value("${cfg.random.uuid}")
private String uuid;
@Value("${cfg.random.test1}")
private int number2;
@Value("${cfg.random.test2}")
private int number3;
}
3.2 配置引用
Spring Boot支持使用占位符获取之前的属性配置,也就是在后一个配置的值中直接引用先前定义过的配置项,直接解析其中的值。这样做的好处是:在多个具有相互关联的配置项中,只需要对其中一处配置项预先设置,其他地方都可以引用。
使用格式为:${name},name表示先前在配置文件中已经设置过的配置项名。
my.database.username=root
spring.datasource.username=${my.database.username}
可以通过冒号设置默认值,当配置项为空或未找到时,使用默认值代替
spring.datasource.username=${my.database.username:root}
4、日志配置
4.1 Spring Boot日志
Spring Boot提供spring-boot-starter-logging组件实现系统日志功能,该组件默认使用LogBack日志记录工具。
在spring-boot-starter-web组件中,默认引入了spring-boot-starter-logging,如果不想使用默认的LogBack日志框架,可以使用exclusions标签关闭,然后引入其他日志框架依赖,如:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除logback-->
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
如果项目不是web项目,则需要单独添加日志组件依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Spring Boot提供了logging.pattern.console和logging.pattern.file配置项来定制日志输出格式,只需要在application.properties文件中添加logging.pattern.console的配置项即可。但是在企业开发中,常常使用xml文件设置日志属性,命名需要注意。
| 日志框架 | 配置文件 |
|---|---|
| Logback | logback-spring.xml , logback.xml |
| Log4j2 | log4j2-spring.xml , log4j2.xml |
logback.xml模板:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<contextName>realtime</contextName>
<!-- 设置日志输出路径 可以使“${}”来使用变量。-->
<property name="log.path" value="logs"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/realtime-info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/logs/realtime-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1000MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/realtime-error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/logs/realtime-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1000MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</configuration>
4.2 日志输出级别
系统的日志级别为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,级别逐渐提高。如果日志级别设置为INFO,则意味着TRACE和DEBUG级别的日志都不会输出。
5、系统多环境配置
实际项目开发过程中,需要面对不同的运行环境,比如开发环境、测试环境、生产环境等,每个环境的配置项都会有所区别。Spring Boot为我们提供了简单方便的配置方案来解决多环境的配置问题。
5.1 创建多环境配置文件
创建多环境配置文件时,需要遵循Spring Boot允许的命名约定来命名,格式为application-{profile}.properties,其中{profile}为对应的环境标识。
一般环境包括开发环境(dev)、测试环境(test)、生产环境(prod),在resources文件夹下添加application.properties、application-dev.properties、application-test.properties、application-prod.properties文件,分别作为项目主配置文件、开发环境配置文件、测试环境配置文件、生产环境配置文件。
5.2 多环境切换
项目打包或者运行时,需要切换到指定的profile环境。指定项目的启动环境有以下3种方式:
(1)配置文件指定项目启动环境
Spring Boot支持通过spring.profiles.active配置项目启动环境,在application.properties配置文件中增加如下配置项指定对应的环境目录:
# 指定系统运行环境
spring.profiles.active=dev
(2)命令行启动指定项目环境
在命令行通过java -jar命令启动项目时,需要如下指定启动环境:
java -jar xxx.jar --spring.profiles.active=dev