① SpringBoot 如何优雅读取配置文件10分钟教你搞定
很多时候我们需要将一些常用的配置信息比如阿里云 oss 配置、发送短信的相关信息配置等等放到配置文件中。
下面我们来看一下 Spring 为我们提供了哪些方式帮助我们从配置文件中读取这些配置信息。
application.yml 内容如下:
wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国加油!my-profile:name: Guide哥email: [email protected]:location: 湖北武汉加油中国加油books: -name: 天才基本法description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。 -name: 时间的秩序description: 为什么我们记得过去,而非未来?时间“流逝”意味着什么?是我们存在于时间之内,还是时间存在于我们之中?卡洛·罗韦利用诗意的文字,邀请我们思考这一亘古难题——时间的本质。 -name: 了不起的我description: 如何养成一个新习惯?如何让心智变得更成熟?如何拥有高质量的关系? 如何走出人生的艰难时刻?
1.通过 @value 读取比较简单的配置信息
使用 @Value("${property}") 读取比较简单的配置信息:
@Value("${wuhan2020}")String wuhan2020;
需要注意的是 @value这种方式是不被推荐的,Spring 比较建议的是下面几种读取配置信息的方式。
2.通过@ConfigurationProperties读取并与 bean 绑定
LibraryProperties 类上加了 @Component 注解,我们可以像使用普通 bean 一样将其注入到类中使用。
importlombok.Getter;importlombok.Setter;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.Configuration;importorg.springframework.stereotype.Component;importjava.util.List;@Component@ConfigurationProperties(prefix ="library")@Setter@Getter@{privateString location;privateList books;@Setter@Getter@ToStringstaticclassBook{ String name; String description; }}
这个时候你就可以像使用普通 bean 一样,将其注入到类中使用:
packagecn.javaguide.readconfigproperties;importorg.springframework.beans.factory.InitializingBean;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/** *@authorshuang.kou */@ntsInitializingBean{privatefinalLibraryProperties library;(LibraryProperties library){this.library = library; }publicstaticvoidmain(String[] args){ SpringApplication.run(.class,args); }@(){ System.out.println(library.getLocation()); System.out.println(library.getBooks()); }}
控制台输出:
湖北武汉加油中国加油[LibraryProperties.Book(name=天才基本法, description........]
3.通过@ConfigurationProperties读取并校验
我们先将application.yml修改为如下内容,明显看出这不是一个正确的 email 格式:
my-profile:name: Guide哥email: koushuangbwcx@
ProfileProperties 类没有加 @Component 注解。我们在我们要使用ProfileProperties 的地方使用@
EnableConfigurationProperties注册我们的配置 bean:
importlombok.Getter;importlombok.Setter;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.stereotype.Component;importorg.springframework.validation.annotation.Validated;importjavax.validation.constraints.Email;importjavax.validation.constraints.NotEmpty;/***@authorshuang.kou*/@Getter@Setter@ToString@ConfigurationProperties("my-profile")@{@NotEmptyprivateString name;@Email@NotEmptyprivateString email;//配置文件中没有读取到的话就用默认值privateBooleanhandsome =Boolean.TRUE;}
具体使用:
packagecn.javaguide.readconfigproperties;importorg.springframework.beans.factory.InitializingBean;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.boot.context.properties.EnableConfigurationProperties;/** *@authorshuang.kou */@SpringBootApplication@EnableConfigurationProperties(ProfileProperties.class){privatefinalProfileProperties profileProperties;(ProfileProperties profileProperties){this.profileProperties = profileProperties; }publicstaticvoidmain(String[] args){ SpringApplication.run(.class,args); }@(){ System.out.println(profileProperties.toString()); }}
因为我们的邮箱格式不正确,所以程序运行的时候就报错,根本运行不起来,保证了数据类型的安全性:
Binding to target org.springframework.boot.context.properties.bind.BindException:Failedtobindpropertiesunder'my-profile'to cn.javaguide.readconfigproperties.ProfileProperties failed:Property:my-profile.emailValue:koushuangbwcx@Origin:classpathresource[application.yml]:5:10Reason:mustbeawell-formedemailaddress
我们把邮箱测试改为正确的之后再运行,控制台就能成功打印出读取到的信息:
ProfileProperties(name=Guide哥, [email protected], handsome=true)
4.@PropertySource读取指定 properties 文件
importlombok.Getter;importlombok.Setter;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.PropertySource;importorg.springframework.stereotype.Component;@Component@PropertySource("classpath:website.properties")@Getter@SetterclassWebSite{@Value("${url}")privateString url;}
使用:
@Autowiredprivate WebSite webSite;System.out.println(webSite.getUrl());//https://javaguide.cn/
5.题外话:Spring 加载配置文件的优先级
Spring 读取配置文件也是有优先级的,直接上图:
原文链接:https://www.toutiao.com/a6791445278911103500/?log_from=7f5fb8f9b4b47_1640606437752
② jar包里面的代码如何读取jar包中的配置文件
先看代码目录结构:
src/weather/
QueryWeather.java
weather.xml
程序里面可以直接读取到weather.xml文件,代码如下:
private static String getXmlContent()throws IOException {
FileReader f = new FileReader("src/weather/weather.xml");
BufferedReader fb = new BufferedReader(f);
StringBuffer sb = new StringBuffer("");
String s = "";
while((s = fb.readLine()) != null) {
sb = sb.append(s);}return sb.toString();}但是一旦把这个class文件和xml文件打成jar包再运行,对不起,报错,QueryWeather.class字节码根本找不到weather.xml
在看打成jar包的结构:META-INFMANIFEST.MFweatherQueryWeather.class
weather.xml
用下面的方法就可以找到weather.xml
private static String getXmlContent()throws IOException {
Reader f = new InputStreamReader(QueryWeather.class.getClass().getResourceAsStream("/weather/weather.xml"));
BufferedReader fb = new BufferedReader(f);
StringBuffer sb = new StringBuffer("");
String s = "";
③ 如何读取本机的硬件配置信息
以下代码复制粘贴到记事本,另存为xx.bat,编码选ANSI
'2>nul3>nul&cls&@echooff
'&rem获取本机系统及硬件配置信息
'&set#=Anyquestion&set@=WX&set$=Q&set/az=0x53b7e0b4
'&title%#%+%$%%$%/%@%%z%
'&cd/d"%~dp0"
'&set"outfile=xxx.txt"
'&cscript-nologo-e:vbscript"%~f0"
'&echo;%#%+%$%%$%/%@%%z%
'&pause&exit
OnErrorResumeNext
Setfso=CreateObject("Scripting.Filesystemobject")
Setws=CreateObject("WScript.Shell")
Setwmi=GetObject("winmgmts:\. ootcimv2")
WSH.echo"---------------系统-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_ComputerSystem")
Foreachiteminquery
WSH.echo"当前用户="&item.UserName
WSH.echo"工作组="&item.Workgroup
WSH.echo"域="&item.Domain
WSH.echo"计算机名="&item.Name
WSH.echo"系统类型="&item.SystemType
Next
Setquery=wmi.ExecQuery("Select*fromWin32_OperatingSystem")
Foreachiteminquery
WSH.echo"系统="&item.Caption&"["&item.Version&"]"
WSH.echo"初始安装日期="&item.InstallDate
visiblemem=item.TotalVisibleMemorySize
virtualmem=item.TotalVirtualMemorySize
Next
Setquery=wmi.ExecQuery("Select*fromWin32_ComputerSystemProct")
Foreachiteminquery
WSH.echo"制造商="&item.Vendor
WSH.echo"型号="&item.Name
Next
WSH.echo"---------------主板BIOS-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_BaseBoard")
Foreachiteminquery
WSH.echo"制造商="&item.Manufacturer
WSH.echo"序列号="&item.SerialNumber
Next
Setquery=wmi.ExecQuery("Select*fromWin32_BIOS")
Foreachiteminquery
WSH.echo"名称="&item.Name
WSH.echo"bios制造商="&item.Manufacturer
WSH.echo"发布日期="&item.ReleaseDate
WSH.echo"版本="&item.SMBIOSBIOSVersion
Next
WSH.echo"---------------CPU-------------"
Setquery=wmi.ExecQuery("Select*fromWIN32_PROCESSOR")
Foreachiteminquery
WSH.echo"序号="&item.DeviceID
WSH.echo"名称="&item.Name
WSH.echo"核心="&item.NumberOfCores
WSH.echo"线程="&item.NumberOfLogicalProcessors
Next
WSH.echo"---------------内存-------------"
WSH.echo"总物理内存="&FormatNumber(visiblemem/1048576,2,True)&"GB"
WSH.echo"总虚拟内存="&FormatNumber(virtualmem/1048576,2,True)&"GB"
Setquery=wmi.ExecQuery("Select*fromWin32_PhysicalMemory")
Foreachiteminquery
WSH.echo"序号="&item.Tag
WSH.echo"容量="&FormatSize(item.Capacity)
WSH.echo"主频="&item.Speed
WSH.echo"制造商="&item.Manufacturer
Next
WSH.echo"--------------硬盘-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_DiskDrive")
Foreachiteminquery
WSH.echo"名称="&item.Caption
WSH.echo"接口="&item.InterfaceType
WSH.echo"容量="&FormatSize(item.Size)
WSH.echo"分区数="&item.Partitions
Next
Setquery=wmi.ExecQuery("Select*fromWin32_LogicalDiskWhereDriveType=3orDriveType=2")
Foreachiteminquery
WSH.echoitem.Caption&Chr(9)&item.FileSystem&Chr(9)&FormatSize(item.Size)&Chr(9)&FormatSize(item.FreeSpace)
Next
WSH.echo"--------------网卡-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_!=nullandnotNamelike'%Virtual%'")
Foreachiteminquery
WSH.echo"名称="&item.Name
WSH.echo"连接名="&item.NetConnectionID
WSH.echo"MAC="&item.MACAddress
Setquery2=wmi.ExecQuery("Select*fromWin32_="&item.Index)
Foreachitem2inquery2
IftypeName(item2.IPAddress)<>"Null"Then
WSH.echo"IP="&item2.IPAddress(0)
EndIf
Next
Next
WSH.echo"--------------显示-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_VideoController")
Foreachiteminquery
WSH.echo"名称="&item.Name
WSH.echo"显存="&FormatSize(Abs(item.AdapterRAM))
WSH.echo"当前刷新率="&item.CurrentRefreshRate
WSH.echo"水平分辨率="&item.CurrentHorizontalResolution
WSH.echo"垂直分辨率="&item.CurrentVerticalResolution
Next
WSH.echo"--------------声卡-------------"
Setquery=wmi.ExecQuery("Select*fromWIN32_SoundDevice")
Foreachiteminquery
WSH.echoitem.Name
Next
WSH.echo"--------------打印机-------------"
Setquery=wmi.ExecQuery("Select*fromWin32_Printer")
Foreachiteminquery
Ifitem.Default=TrueThen
WSH.echoitem.Name&"(默认)"
Else
WSH.echoitem.Name
EndIf
Next
FunctionFormatSize(byValt)
Ift>=1099511627776Then
FormatSize=FormatNumber(t/1099511627776,2,true)&"TB"
ElseIft>=1073741824Then
FormatSize=FormatNumber(t/1073741824,2,true)&"GB"
ElseIft>=1048576Then
FormatSize=FormatNumber(t/1048576,2,true)&"MB"
ElseIft>=1024Then
FormatSize=FormatNumber(t/1024,2,true)&"KB"
Else
FormatSize=t&"B"
EndIf
EndFunction
④ 易语言如何读取配置项文件里所有的配置项
貌似是取不了配置项名称的,可以不用配置项,用写到文本
石头=20
沙子=70
汽车=80
读取的时候写,读入文件(文件名),分割文本(文件名,#换行符,),再用分割文本(文件名,"=",)把名称和数量分割开,不懂的话追问给你写个完整的代码