一、简介
实际开发过程中,我们经常要获取配置文件的值,来实现我们程序的可配置化,今天我们就来看看spring boot里获取配置文件值的几种方式。
二、依赖和配置
2.1、maven依赖
本文中spring boot的版本为当前最新版(当前最新为2.5.2)
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.5.2</version>
<relativepath/>
</parent>
<groupid>com.alian</groupid>
<artifactid>properties</artifactid>
<version>0.0.1-snapshot</version>
<name>properties</name>
<description>spring boot读取配置文件的值</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter</artifactid>
<version>${parent.version}</version>
</dependency>
<!--@propertysource使用到-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-configuration-processor</artifactid>
<version>${parent.version}</version>
<optional>true</optional>
</dependency>
<!--本项目也可以不引用-->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
<version>${parent.version}</version>
</dependency>
<!--@data或日志使用到-->
<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>
<version>1.16.14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>大家可以根据自己项目的需要进行选择。
2.2、application.properties配置
application.properties
#如果引用了
#<dependency>
# <groupid>org.springframework.boot</groupid>
# <artifactid>spring-boot-starter-web</artifactid>
# <version>${parent.version}</version>
#</dependency>
#则配置项目名和端口
server.port=8897
server.servlet.context-path=/properties因为我本地是建了一个web项目
三、实践(后面的实例全部采用@postconstruct测试)
3.1、@value方式获取
语法如下:
@value(${配置项key:默认值})
private string configvalue;
注意:@value是org.springframework.beans.factory.annotation.value
我们在配置文件application.properties中新增如下配置,用于测试@value方式获取配置文件的值
#定义@value的变量测试 #请求地址 value.request.url=https://openapi.alipay.com/gateway.do #请求应用id value.request.app.id=2019052960295228 #请求签名key value.request.sign.key=ffffea911121494981c5feba599c3a99 #请邱加密key value.request.encrypted.key=eeee9ca14de545768a0bd9f1435ee507
@value测试源程序
valueservice.java
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("${value.request.url}")
private string url;
/**
* 请求应用id
*/
@value("${value.request.app.id}")
private string appid;
/**
* 请求签名key
*/
@value("${value.request.sign.key}")
private string signkey;
/**
* 请求加密key
*/
@value("${value.request.encrypted.key}")
private string encryptedkey;
/**
* 超时时间(默认值设置,当没有获取到配置值时,用冒号分隔,写在冒号后面)
*/
@value("${value.request.timeout: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测试获取的请求地址:https://openapi.alipay.com/gateway.do
@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 是org.springframework.core.env.environment
我们继续在配置文件application.properties中新增如下配置,用于测试environment 方式获取配置文件的值
#定义environment的变量测试 #系统组 envir.system.group=alian #系统组 envir.system.level=1 #系统名称 envir.system.name=administrator #系统密码 envir.system.password=e6fa5927cc37437ac6cbe5e988288f80
environment测试源程序
environmentservice.java
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("envir.system.group"));
system.out.println("environment测试获取的系统级别:" + environment.getproperty("envir.system.level"));
system.out.println("environment测试获取的系统名:" + environment.getproperty("envir.system.name"));
system.out.println("environment测试获取的系统密码:" + environment.getproperty("envir.system.password"));
//如果配置文件未设置该key的值,则使用默认值
system.out.println("environment测试获取的默认值设置:" + environment.getproperty("envir.system.init", "未设置初始化参数"));
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对象即可使用。
我们继续在配置文件application.properties中新增如下配置,用于测试@configurationproperties方式获取配置文件的值
##定义properties的变量测试 #作者 app.author-name=alian #博客网站 app.web-url=https://blog.csdn.net/alian_1223 #小程序应用id app.micro-applet.app-id=wx4etd7e3803c6c555 #小程序应用secretid app.micro-applet.secret-id=e6fa5627cc57437ac8cbe5e988288f80 #小程序超时时间 app.micro-applet.expire-time=3600
废话不多少,直接新建一个配置类appproperties.java
appproperties.java
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 = "https://blog.csdn.net/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 = appproperties.class))
- 如果有内部类对象,记得加上@data,不然无法映射数据
- .properties类型文件映射规则,短横线(-)后面的首个字母会变成大写,同时注意有内部类时的写法
使用方法也很简单,直接使用spring的注解@autowired引入即可
@autowired
private appproperties appproperties;
appproperties测试源程序
propertiesservice.java
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测试获取的博客地址:https://blog.csdn.net/alian_1223
properties测试获取的小程序应用id:wx4etd7e3803c6c555
properties测试获取的小程序secretid:e6fa5627cc57437ac8cbe5e988288f80
properties测试获取的小程序超时时间:3600
-------------------properties测试结束-------------------
注意:
- 类型转换少,配置类可以直接定义常规类型
- 配置分类方便,一个地方维护,不用一个key到处写
- 更符合面向对象的写法
- spring boot注解读取application.properties或者application-{profile}.properties文件时默认编码是iso_8859_1,读取yaml配置文件时使用的是utf-8的编码方式,如果有中文配置请使用.yml格式,或者使用我接下来的读取方式。
3.4、@propertysource方式获取
有时候我们会有一些特殊意义的配置,会单独用一个配置文件存储,比如数据库配置连接参数,同样我们在application.properties同级目录新建一个配置文件alian.properties,内容如下:
alian.properties
#博客用户 csdn.user-name=alian #博客密码 csdn.password=123456 #博客地址 csdn.blog-url=https://blog.csdn.net/alian_1223 #博客描叙 csdn.blog-desp=来来来,一起聊干货!!!
新建一个配置类alianproperties.java来完成映射
alianproperties.java
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 = "csdn")
@propertysource(value = "classpath:alian.properties", encoding = "utf-8", ignoreresourcenotfound = true)
public class alianproperties {
private string username;
private string password;
private string blogurl;
private string blogdesp;
}
注意:
- @configurationproperties(value = “csdn”)表示配置文件里属性的前缀都是csdn开头
- @propertysource中value属性表示指定配置文件的路径,encoding属性表示指定的是读取配置文件时的编码,记得和文件alian.properties的编码保持一致,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测试获取的数据库地址:https://blog.csdn.net/alian_1223
properties测试获取的数据库用户名:alian
properties测试获取的数据库密码:123456
properties测试获取的数据库连接参数:来来来,一起聊干货!!!
-------------------placesource测试结束-------------------
3.5、原生方式获取
原生方式大家都懂,就不过多介绍了,直接上代码
loadpropertiesservice.java
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("load.properties")), standardcharsets.utf_8);
props.load(inputstreamreader);
} catch (ioexception e1) {
e1.printstacktrace();
}
system.out.println("loadproperties测试获取的功能名称:" + props.getproperty("function.name"));
system.out.println("loadproperties测试获取的功能描述:" + props.getproperty("function.desp"));
system.out.println("-------------------loadproperties测试开始-------------------");
}
}
运行结果:
-------------------loadproperties测试开始-------------------
loadproperties测试获取的功能名称:loadproperties
loadproperties测试获取的功能描述:原生获取配置文件的值
-------------------loadproperties测试开始-------------------
注意:
- 读取流的时候指定好编码,保证和文件的编码一致,否则会导致乱码
结语
本文主要介绍了几种读取配置文件的方式,实际工作中,前面三种方式用得比较多,当然以后有了spring cloud配置中心,使用我推荐的方式结合@refreshscope即可完成配置文件动态刷新。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论