目录
- 一、简介
- 二、依赖和配置
- 2.1、maven依赖
- 2.2、配置
- 三、实践(后面的实例全部采用@PostConstruct测试)
- 3.1、@Value方式获取
- 3.2、Environment对象获取
- 3.3、@ConfigurationProperties方式获取(强烈推荐)
- 3.4、@PropertySource方式获取
- 3.5、原生方式获取
- 结语
一、简介
实际开发过程中,我们经常要获取配置文件的值,来实现我们程序的可配置化,今天我们就来看看Spring Boot里获取配置文件值的几种方式。
二、依赖和配置
2.1、maven依赖
本文中Spring Boot的版本为当前最新版(当前最新为2.5.2)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="http:///2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId></groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/>
</parent>
<groupId></groupId>
<artifactId>properties</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>properties</name>
<description>Spring Boot读取配置文件的值</description>
<properties>
<>1.8</>
</properties>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${}</version>
</dependency>
<!--@PropertySource使用到-->
<dependency>
<groupId></groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${}</version>
<optional>true</optional>
</dependency>
<!--本项目也可以不引用-->
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${}</version>
</dependency>
<!--@Data或日志使用到-->
<dependency>
<groupId></groupId>
<artifactId>lombok</artifactId>
<version>1.16.14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId></groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
大家可以根据自己项目的需要进行选择。
2.2、配置
#如果引用了
#<dependency>
# <groupId></groupId>
# <artifactId>spring-boot-starter-web</artifactId>
# <version>${}</version>
#</dependency>
#则配置项目名和端口
=8897
-path=/properties
因为我本地是建了一个web项目
三、实践(后面的实例全部采用@PostConstruct测试)
3.1、@Value方式获取
语法如下:
@Value(${配置项key:默认值})
private String configValue;
注意:@Value是
我们在配置文件中新增如下配置,用于测试@Value方式获取配置文件的值
#定义@Value的变量测试
#请求地址
=https:///
#请求应用id
=2019052960295228
#请求签名key
=FFFFEA911121494981C5FEBA599C3A99
#请邱加密key
=EEEE9CA14DE545768A0BD9F1435EE507
@Value测试源程序
package com.alian.properties.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class ValueService {
/**
* 请求地址
*/
@Value("${}")
private String url;
/**
* 请求应用id
*/
@Value("${}")
private String appId;
/**
* 请求签名key
*/
@Value("${}")
private String signKey;
/**
* 请求加密key
*/
@Value("${}")
private String encryptedKey;
/**
* 超时时间(默认值设置,当没有获取到配置值时,用冒号分隔,写在冒号后面)
*/
@Value("${:20}")
private int timeOut;
@PostConstruct
public void testValue() {
System.out.println("-------------------@Value测试开始-------------------");
System.out.println("@Value测试获取的请求地址:" + url);
System.out.println("@Value测试获取的请求应用id:" + appId);
System.out.println("@Value测试获取的请求签名key:" + signKey);
System.out.println("@Value测试获取的请求加密key:" + encryptedKey);
//如果配置文件未设置该key的值,则使用默认值
System.out.println("@Value测试获取的默认值设置:" + timeOut);
System.out.println("-------------------@Value测试结束-------------------");
}
}
运行结果:
-------------------@Value测试开始-------------------
@Value测试获取的请求地址:/
@Value测试获取的请求应用id:2019052960295228
@Value测试获取的请求签名key:FFFFEA911121494981C5FEBA599C3A99
@Value测试获取的请求加密key:EEEE9CA14DE545768A0BD9F1435EE507
@Value测试获取的默认值设置:20
-------------------@Value测试结束-------------------
注意:
- 使用@Value方式获取配置文件的值,如果配置项的key不存在,也没有设置默认值,则程序直接报错
- 使用@Value方式默认值的设置方法:配置项的key后面加冒号然后写默认值如:${配置项的key:默认值}
- 使用@Value方式如果是配置文件里配置项太多,并且使用的地方过多的时候,维护和管理不太方便
3.2、Environment对象获取
使用很简单,直接使用spring的注解@Autowired引入即可
@Autowired
private Environment environment;
注意:Environment 是
我们继续在配置文件中新增如下配置,用于测试Environment 方式获取配置文件的值
#定义Environment的变量测试
#系统组
=Alian
#系统组
=1
#系统名称
=administrator
#系统密码
=e6fa5927cc37437ac6cbe5e988288f80
Environment测试源程序
package com.alian.properties.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class EnvironmentService {
@Autowired
private Environment environment;
@PostConstruct
public void testEnvironment() {
System.out.println("-------------------Environment测试开始-------------------");
System.out.println("Environment测试获取的系统组:" + environment.getProperty(""));
System.out.println("Environment测试获取的系统级别:" + environment.getProperty(""));
System.out.println("Environment测试获取的系统名:" + environment.getProperty(""));
System.out.println("Environment测试获取的系统密码:" + environment.getProperty(""));
//如果配置文件未设置该key的值,则使用默认值
System.out.println("Environment测试获取的默认值设置:" + environment.getProperty("", "未设置初始化参数"));
System.out.println("-------------------Environment测试结束-------------------");
}
}
运行结果:
-------------------Environment测试开始-------------------
Environment测试获取的系统组:Alian
Environment测试获取的系统级别:1
Environment测试获取的系统名:administrator
Environment测试获取的系统密码:e6fa5927cc37437ac6cbe5e988288f80
Environment测试获取的默认值设置:未设置初始化参数
-------------------Environment测试结束-------------------
注意:
- 使用Environment对象获取配置文件的值,最好使用带默认值的方法:getProperty(“配置项key”,“默认值”),避免null值
- 使用Environment对象还可以获取到一些系统的启动信息,当然如果配置项过多也会有维护管理方面的问题
3.3、@ConfigurationProperties方式获取(强烈推荐)
为了更契合java的面向对象,我们采用自动配置的方式映射配置文件属性,配置完成后直接当做java对象即可使用。我们继续在配置文件中新增如下配置,用于测试@ConfigurationProperties方式获取配置文件的值
##定义Properties的变量测试
#作者
-name=Alian
#博客网站
-url=https:///Alian_1223
#小程序应用id
--id=wx4etd7e3803c6c555
#小程序应用secretId
--id=e6fa5627cc57437ac8cbe5e988288f80
#小程序超时时间
--time=3600
废话不多少,直接新建一个配置类
package com.alian.properties.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(value = "app")
public class AppProperties {
/**
* 作者名称
*/
private String authorName = "";
/**
* 博客网站
*/
private String webUrl = "/Alian_1223";
/**
* 小程序配置
*/
private MicroApplet microApplet;
@Data
public static class MicroApplet {
/**
* 应用id
*/
private String appId = "";
/**
* secretId
*/
private String secretId = "";
/**
* 过期时间
*/
private int expireTime = 30;
}
}
注意:
- @ConfigurationProperties(value = “app”)表示的配置文件里属性的前缀都是app开头
- 配置类上记得加上@Data和@Component注解(或者在启动类上加上@EnableConfigurationProperties(value = ))
- 如果有内部类对象,记得加上@Data,不然无法映射数据
- .properties类型文件映射规则,短横线(-)后面的首个字母会变成大写,同时注意有内部类时的写法
使用方法也很简单,直接使用spring的注解@Autowired引入即可
@Autowired
private AppProperties appProperties;
AppProperties测试源程序
package com.alian.properties.service;
import com.alian.properties.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class PropertiesService {
@Autowired
private AppProperties appProperties;
@PostConstruct
public void testProperties() {
System.out.println("-------------------Properties测试开始-------------------");
System.out.println("Properties测试获取的作者:" + appProperties.getAuthorName());
System.out.println("Properties测试获取的博客地址:" + appProperties.getWebUrl());
System.out.println("Properties测试获取的小程序应用id:" + appProperties.getMicroApplet().getAppId());
System.out.println("Properties测试获取的小程序SecretId:" + appProperties.getMicroApplet().getSecretId());
System.out.println("Properties测试获取的小程序超时时间:" + appProperties.getMicroApplet().getExpireTime());
System.out.println("-------------------Properties测试结束-------------------");
}
}
运行结果:
-------------------Properties测试开始-------------------
Properties测试获取的作者:Alian
Properties测试获取的博客地址:/Alian_1223
Properties测试获取的小程序应用id:wx4etd7e3803c6c555
Properties测试获取的小程序SecretId:e6fa5627cc57437ac8cbe5e988288f80
Properties测试获取的小程序超时时间:3600
-------------------Properties测试结束-------------------
注意:
- 类型转换少,配置类可以直接定义常规类型
- 配置分类方便,一个地方维护,不用一个key到处写
- 更符合面向对象的写法
- Spring Boot注解读取或者application-{profile}.properties文件时默认编码是ISO_8859_1,读取yaml配置文件时使用的是UTF-8的编码方式,如果有中文配置请使用.yml格式,或者使用我接下来的读取方式。
3.4、@PropertySource方式获取
有时候我们会有一些特殊意义的配置,会单独用一个配置文件存储,比如数据库配置连接参数,同样我们在同级目录新建一个配置文件,内容如下:
#博客用户
-name=Alian
#博客密码
=123456
#博客地址
-url=https:///Alian_1223
#博客描叙
-desp=来来来,一起聊干货!!!
新建一个配置类来完成映射
package com.alian.properties.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "****")
@PropertySource(value = "classpath:", encoding = "UTF-8", ignoreResourceNotFound = true)
public class ALianProperties {
private String userName;
private String password;
private String blogUrl;
private String blogDesp;
}
注意:
- @ConfigurationProperties(value = “****”)表示配置文件里属性的前缀都是****开头
- @PropertySource中value属性表示指定配置文件的路径,encoding属性表示指定的是读取配置文件时的编码,记得和文件的编码保持一致,ignoreResourceNotFound属性值为true时没找到指定配置文件的时候不报错
- 配置类上记得加上@Component注解
- .yml 格式不支持@PlaceSource注解导入配置
使用方法也很简单,直接使用spring的注解@Autowired引入即可
@Autowired
private ALianProperties ALianProperties;
@PlaceSource测试源程序
PlaceSourceService .java
package com.alian.properties.service;
import com.alian.properties.config.ALianProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class PlaceSourceService {
@Autowired
private ALianProperties ALianProperties;
@PostConstruct
public void testPlaceSource() {
System.out.println("-------------------PlaceSource测试开始-------------------");
System.out.println("Properties测试获取的数据库地址:" + ALianProperties.getBlogUrl());
System.out.println("Properties测试获取的数据库用户名:" + ALianProperties.getUserName());
System.out.println("Properties测试获取的数据库密码:" + ALianProperties.getPassword());
System.out.println("Properties测试获取的数据库连接参数:" + ALianProperties.getBlogDesp());
System.out.println("-------------------PlaceSource测试结束-------------------");
}
}
运行结果:
-------------------PlaceSource测试开始-------------------
Properties测试获取的数据库地址:/Alian_1223
Properties测试获取的数据库用户名:Alian
Properties测试获取的数据库密码:123456
Properties测试获取的数据库连接参数:来来来,一起聊干货!!!
-------------------PlaceSource测试结束-------------------
3.5、原生方式获取
原生方式大家都懂,就不过多介绍了,直接上代码
package com.alian.properties.service;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Properties;
@Service
public class LoadPropertiesService {
@PostConstruct
public void testLoadProperties() {
System.out.println("-------------------LoadProperties测试开始-------------------");
Properties props = new Properties();
try {
InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("")), StandardCharsets.UTF_8);
props.load(inputStreamReader);
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("LoadProperties测试获取的功能名称:" + props.getProperty(""));
System.out.println("LoadProperties测试获取的功能描述:" + props.getProperty(""));
System.out.println("-------------------LoadProperties测试开始-------------------");
}
}
运行结果:
-------------------LoadProperties测试开始-------------------
LoadProperties测试获取的功能名称:loadProperties
LoadProperties测试获取的功能描述:原生获取配置文件的值
-------------------LoadProperties测试开始-------------------
注意:
- 读取流的时候指定好编码,保证和文件的编码一致,否则会导致乱码
结语
本文主要介绍了几种读取配置文件的方式,实际工作中,前面三种方式用得比较多,当然以后有了spring cloud配置中心,使用我推荐的方式结合@RefreshScope即可完成配置文件动态刷新。