Spring Boot依靠“约定优于配置”的思想,为绝大多数配置项都约定了默认值,使得Spring Boot方便使用。当然在在实际开发过程中,有时候还是需要对项目进行一些配置的,比如数据库连接、服务端口号等等。这章我们就介绍一下Spring Boot中如和进行项目配置。
我们可以通过项目的全局配置文件来对Spring Boot项目的一些默认值进行修改。Spring Boot支持两种不同格式的配置文件,默认分别是application.properties和application.yml(或者application.yaml)。Spring Boot默认使用application.properties作为系统配置文件。使用Spring Initializr构建的Spring Boot项目,会在resource目录下默认添加一个空的application.properties文件,我们可以在application.properties文件中配置Spring Boot项目相关的属性,这些属性可以是服务端口、命令参数、环境变量、数据库连接配置等。
配置示例
# 项目配置示例
server.port=8083
datasource.type=dbcp
#mysql
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=@RFV13f5
application.properties文件中采用了 配置项=配置值 的语法,很容易掌握。对于有哪些配置可以查看Spring Boot的官网或者依赖项的官网,如果使用IDEA进行开发,在配置时IDEA会自动弹出提示帮助开发人员进行配置
Spring Boot 项目的默认配置文件名为application.proerties,但其实这不是固定不变的,开发人员可以通过修改项目启动类中的代码实现更改。具体操作如下
new SpringApplicationBuilder(ApplicationDemo.class)
.properties("spring.config.location=classpath:/application.pro")
.run(args)
上面代码通过调用SpringApplicationBuilder类的properties()方法实现修改默认配置文件名。
Spring Boot项目的配置文件默认在resources目录中,但在Spring Boot启动时它会在4个地方读取配置文件,并且优先级逐渐升高,如果相同的属性都出现在这4个目录中的配置文件里
application.yml文件有时候也写作application.yaml文件,YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。相对于XML文件来说,YAML文件的语法和其他高级语言类似,但是在表达清单、散列表,标量等数据形态参数上有独特优势。
YAML基础语法
其基本语法为key: <空格> value的键值对形式,冒号后面必须加上空格(主要这里的<>是为了突出显示,实际是不需要的)。YAML通过空格的缩进来控制属性的层级关系,只要是左对齐的同一列数据,就都是同一个层级。
value值为普通数据类型
这里的普通数据类型,又称之为纯量,即不可再分割的量,主要有
当YAML配置文件中的属性值为纯量时,可以直接配置对应的属性值,同时如果是字符串类型的属性值,不需要额外添加引号
server:
port: 8083
path: /helloworld
数组
以-开头的行表示构成一个数组
Array1:
- A1
- A2
- A3
或者写成
Array1:
A1,
A2,
A3,
以-开头的表示方法又称缩进式,除此之外还有一种行内式表示法
Array1: [A1,A2,A3]
value值为Map集合和对象
当YAML配置文件中配置的属性值为Map集合或者对象类型是,同样可以使用缩进式和行内式
缩进式写法
myobj:
map:
k1: v1
k2: v2
k3: v3
行内式写法
myobj:
map: {k1: v1, k2: v2, k3: v3}
在YAML配置文件中,配置的属性值为Map集合或者对象数据类型时注意行内式的属性值要用大括号"{}"包含起来。
Spring Boot中properties和YAML文件均可以使用,一般情况可以根据开发需求和使用习惯自由选择。不过这两种配置文件有不同的侧重点,分别适合不同的场景。
properties文件的优先级高于YAML文件。如果两个文件存在相同的配置,则properties文件中的属性最终起作用。
properties文件对内容的格式要求宽松,不易出错,但YAML文件以空格缩进控制层级关系,对格式要求叫高,开发中一不注意容易出错。
properties文件支持@PropertySource注解,YAML文件不支持。
YAML文件对数据的支持和展现非常好,对于需要处理很多格式数据的项目比较方便。
SpringBoot虽然有很多的默认配置项可供开发人员配置,但是在具体的项目开发过程中,项目中经常有需要针对项目业务的专用配置项,面对这种需求Spring Boot 通过提供@Value注解、@ConfigurationProperties注解和Environment接口等方式让开发人员自定义配置项。
实际上@Value 注解是Spring框架提供的,它可以读取配置文件中的属性值并且逐个注入指定的Bean对象对应的属性中。Spring Boot对Spring中的@Value注解进行了默认继承,所以 Spring Boot中的@Value 注解可以用来设置简单的配置项,该注解通知框架默认从application.properties文件中读取相应属性然后注入到需要的Bean中具体用法如下
我们计划在通过配置文件中的配置给一个Boy的类注入name和age,我们在application.properties中填写
boy.name=xiaoming
boy.age=6
然后我们编写需要将配置注入的Bean,一般来说Bean文件在项目开发时会放到同一个目录下,这里我们新建一个目录model,然后在其中添加一个Boy的Java文件,其中toString函数可以通过在类中右击,选择Generate,再选择toString(),然后根据提示生成
完整的Boy.java文件如下
package com.cjl.chapter03.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Boy {
@Value("${boy.name}")
private String name;
@Value("${boy.age}")
private int age;
@Override
public String toString() {
return "Boy{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
随后根据前面章节说的方法,生成一个toString函数的单元测试文件
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;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(SpringRunner.class)
@SpringBootTest
class BoyTest {
@Autowired
private Boy boy;
@Test
void testToString() {
System.out.printf(boy.toString());
}
}
右击运行可以看到输出,这说明程序成功从application.porperties中读取到相应的配置并注入到了Boy的实例中
使用@Value可以一个一个指定哪些值注入相应的属性,但是如果遇到一次需要批量注入大量属性值的情况时使用@ConfigurationProperties注解更为方便。该注解是一个Spring Boot框架自有的注解,不像@Value是Spring Boot框架从Spring中默认继承的。
在application.properties文件中我们修改一下原来的配置
boy.name=xiaoqiang
boy.age=7
修改Boy.java文件,为属性添加get和set函数,这个也可以通过IDEA的Generate生成
然后按照如下方式对Bean进行注解
package com.cjl.chapter03.model;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "boy")
public class Boy {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Boy{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
完成之后,Spring Boot会通过从application.properties中读取以boy开头的配置,按照配置名和Bean中属性名一一对应的原则进行注入,注意如果两者属性名不一致则无法获取并注入属性值。然后运行测试程序,输出如下信息,说明配置已经注入成功。
配置注入的注意事项,对于简单值的配置推荐使用@Value,复杂对象推荐使用@ConfigurationProperties。由于只有Spring容器中的组件才能使用容器提供的各类方法,所以,配置读取类需要增加@Component注解告诉Spring Boot这是一个容器组件,才能使用前述的配置注入。
在我们开发过程中,经常遇到一个配置项由其他配置项组成,类似Java中SringC = StringA + StringB一样。对于这种情况Spring Boot提供了后一个配置的值中直接引用先前定义过的配置项的方法。使用方法是:${setName},setName表示先前在配置文件中已经设置过的配置项名。例如我们修改application.properties配置文件,示例代码如下
boy.name=xiaoming
boy.age=6
boy.des=boy name is ${boy.name},my age is ${boy.age}
实际项目运行时将会使用xiaoming替代${boy.name},最终boy.des=boy name is xiaoming ,这时候会有人文如果boyname没有定义或者一不小心被人删除了那怎么办?不用担心Spring Boot提供了默认值的,解决方案通过":"语法指定一个默认值,当引用的值没有定义时,为属性赋值默认值。
boy.des=boy name is ${boy.name:xiaoqiang}
当系统没有找到boy.name配置项时,会默认使用xiaoqiang替代,这样保证系统依然能够提供基础服务。
对于工程中上线运行的项目来说,系统日志非常重要,日志能够帮助开发人员监控系统运行状态,另外特别是在系统出现异常时,日志是帮助开发人员定位问题的关键信息。所以对于每个正式的Spring Boot项目都建议引入日志依赖项,并且对其进行适当的配置,使其能发挥最大效应。
Spring Boot提供了一个依赖项,spring-boot-starter-logging通过它实现系统日志功能,spring-boot-starter-logging组件默认使用LogBack日志记录工具。我们需要修改pom.xml文件,添加spring-boot-starter-logging依赖来引入
org.springframework.boot
spring-boot-starter-logging
在Spring Boot项目中配置日志功能之后,日志会按照约定好的配置输出,
一般日志输出会包含以下内容,按从左到右顺序为:
日期时间:以毫秒为单位
日志级别:ERROR、WARN、INFO、DEBUG、TRACE
进程ID(Process ID)
分离标志来区分实际日志消息的开始 [--- ]
线程名称:用方括号括起来(可能会截断控制台输出)
记录器名称:这通常是源类名称(通常缩写)。
日志消息
对于项目的日志,一般会根据信息的重要程度进行等级划分,以方便开发人员查阅。我们可以通过在 application.properties中配置 logging.level.
logging.level.root=INFO
logging.level.com.cjl.chapter03.log=WARN
但是很多时候我们开发的项目需要控制日志输出,这些都可以进行配置,模认情况下,会记录ERROR-level,WARN-level和INFO-level消息,需要修改输出等级可以在 application.properties 中指定 debug=true,启用调试模式。也可以指定 trace=true动应用程序来启用“跟踪”模式。
默认情况下,Spring Boot仅记录到控制台,不会写入日志文件。如果除了控制台输出之外还要写入日志文件,则需要在 application.properties 配置文件中设置 logging.file 或 logging.path 属性。
logging.file:写入指定的日志文件。名称可以是精确位置或相对于当前目录。
logging.path:写入指定的目录,名称可以是精确位置或相对于当前目录,日志文件名为 spring.log。
logging.file 优先级大于 logging.path,另外日志文件在达到 10 MB 时会轮换,可以使用 logging.file.max-size 属性更改大小限制。
一般在实际开发过程中项目有不同的运行环境,比如开发环境、测试环境、生产环境,在项目开发阶段在开发环境中部署运行,使用开发环境的资源配置参数,而开发完毕后再正式上线之前需要到测试环境进行测试,测试没有问题了才会部署到生产环境。如果使用一个配置文件,每次切换环境时手动修改,不仅费时费力,而且容易出错,特别是如果在生产环境出错,将会带来重大损失,因此需要项目可以针对不同环境快速准确的切换配置。
Spring Boot框架提供了多环境配置的方法,开发人员可以通过配置选择Profile文件进行多环境配置
Spring Boot中可以在默认的配置文件application.properties中选择性激活不同的配置文件,但是被激活的配置文件需要满足application-{profile}.properties的格式,其中{profile}对应具体的环境标识,通常命名形式如下
application-dev.properties //用于开发环境的配置文件
application-test.properties //用于测试环境的配置文件
application-prod.properties //用于生产环境的配置文件
在不同的配置文件中添加不同的信息分别是
boy.name=xiaoqiang in dev
boy.name=xiaoqiang in test
boy.name=xiaoqiang in prod
有了这些配置文件,需要进行选择使用时,选择方式有几种
#选择使用测试环境配置
spring.profiles.active=dev
运行前面编写的单元测试用例,输出属于dev的配置,说明配置成功
可以使用命令行参数选择配置文件,例如在命令行中可用执行下列命令激活环境
java -jar xxx.jar --spring.profile.active=dev
项目源码
可以访问:GitHub - qwdzq/springboot: spring boot 入门
文章有帮助,还请点赞啊