https://www.cnblogs.com/mzywucai/p/11053329.html
想要忽略properties中的某些屬性,引發的對SpringBoot中的application.properties外部注入覆蓋,以及properties文件使用的思考。
SpringBoot 配置文件application.properties配置參數替換或者注入的幾種方式
之所以研究這個問題,原因是因為,我的項目如果通過git備份到碼雲上之后,mysql以及redis的密碼也保存上去了,這樣肯定是不行的,但是我如果忽略application.properties的話,就缺失了關鍵的配置信息;該怎么辦呢?
我開始的想法是能不能把這些密碼參數放到另一個properties中,然后通過注入(類似把properties中的常量注入到java文件中,或者是properties文件,同一個文件內引用${}的方式),所以按照這種注入的思維百度了很久,但是都沒有找到解決辦法…
加載順序引入
后來師兄告訴我,你可以通過SpringBoot加載目錄順序來進行配置文件優先級覆蓋,不用注入,在另一個地方寫一個application.properties,利用SpringBoot加載順序不同,優先級不同,在resources目錄下新建一個config目錄,在config目錄下新建一個application.properties,在resources/config/application.properties下的配置加上密碼之類的,而resources/application.properties中放上配置信息,所有的密碼地址,等隱私信息給成默認的值就行了,比如localhost或者root
注意:這里的加載順序是越往后越優先,后面覆蓋前面的,和SpringBoot靜態資源的順序不同
順便補充靜態資源的加載順序:/META-INF/resources/ > /resources/ > /static/ > /public/,這種順序不同,當然如果你在application.properties中重寫了spring.resources.static-locations,那另當別論,重寫之后按照定義的順序進行加載
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/mzywucai/
師兄說了之后,我就去了解了一下SpringBoot的加載順序:
SpringBoot配置文件的加載順序
SpringBoot的配置文件可以放在四個地方,讀取順序不同(以下yml和properties均是如此):
讀取順序分別是(越靠前越優先,優先越高的地方讀取到了就不會讀取后面的了)
1.項目根目錄中的config/application.properties
2.項目根目錄下的application.properties
3.項目src/main/resources/config/下的appliacation.properties
4.項目src/main/resources/下的application.properties(我們最常見的那個application.properties)
java -jar 時參數注入application.properties核心參數
但是我又出現了一個問題,在做完學院的設備管理之后,老師要求系統要改改占用的端口,方便管理,但是我每次只改一個server.port就要重新打包,豈不是很不划算?
所以看到了那啥快看的博客園,讀了博主的文章,還額外解除了許多疑惑!
1.參數通過properties注入類的時候,如果是在application.properties中不用加上@PropertySource({“classpath:application.properties”})
// 博主在文中寫到,如果是在application.properties中的常量, // 那么忘類中注入常量的時候,就不用在類上面聲明 // @PropertySource({"classpath:application.properties"}) // 只有在名字為其它的properties配置文件的時候,才需要聲明@PropertySource({"xxx.properties"}) // 例如: // @PropertySource({"classpath:resource.properties"}) // 然后在類中的成員變量上加上注解:@Value("${配置文件的全名稱}") 就行了 // 可以看到這里的@PropertySource({"xxx.properties", "xxx", "yyy"})里面是個對象,可以加載多個properties文件 // 有時候我們注入的參數過多,並且前綴相同的時候 // 就可以使用 @ConfigurationProperties(prefix = "test") // 但是此時切記不要寫@Value("${}"),加了前綴之后,就是自動注入了,不能再加@Value("${}")注解了 // 案例如下:
案例:
# resource.properties中的內容
# 測試配置文件注入實體類
test.name=mzywucai
test.domain=192.168.60.179,192.168.60.180,192.168.60.181
# 利用值注入還可以做很多有趣兒的事情,比如隨機值的生成,可以簡化代碼
# 那啥快看的博客園
# ---------------------------------
dudu.secret=${random.value}
dudu.number=${random.int}
dudu.bignumber=${random.long}
dudu.uuid=${random.uuid}
dudu.number.less.than.ten=${random.int(10)}
dudu.number.in.range=${random.int[1024,65536]}
# ---------------------------------
package club.mzywcuai.springbootquickstart.pojo.domain; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * @author mzywucai * @Description * @date 2018/10/21 */ @Component // 加此注解是為了讓SpringBoot掃描 // 如果是application.properties就不用寫了! @PropertySource({"classpath:resource.properties"}) // @ConfigurationProperties // 此注解對應下面使用@Value手動分配的時候 // 注意如果寫了前綴了的話,就不用寫@Value("${xxx...}")了 // 就自動幫我們映射了!但是注意properties中出去前綴后的部分要和我們的實體類中的字段名要相同! @ConfigurationProperties(prefix = "test") public class ServerSettings { // 名稱 // @Value("${test.name}") private String name; // 域名地址 // @Value("${test.domain}") private String domain; public ServerSettings() {} public ServerSettings(String name, String domain) { this.name = name; this.domain = domain; } public void setName(String name) { this.name = name; } public void setDomain(String domain) { this.domain = domain; } public String getName() { return name; } public String getDomain() { return domain; } }
補充:還有properties的key-value,在properties的參數間引用(我的文件服務器的案例):
server.port=10086
# 主服務器的url,通信確認有資格上傳:暫時不會使用
server.main.url=http://localhost:8888/confirm-session
# 文件的路徑的base:
## 此處的路徑進的修改:ubuntu下可以在用戶目錄下 nohup java -jar xxx & 啟動就好了
## 如果是其它目錄的話:加上sudo -> nohup sudo java -jar xxx &
server.file.base=/home/ubuntu/upload
# server.file.base=D:/upload
# 瀏覽器訪問的時候的URI前綴
server.voice.uri=voice
server.video.uri=video
server.image.uri=image
# 語音的路徑
server.file.voice=${server.file.base}/${server.voice.uri}
# 視頻的路徑
server.file.video=${server.file.base}/${server.video.uri}
# 圖片的路徑
server.file.image=${server.file.base}/${server.image.uri}
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${server.file.base}
# 單個文件大小為20M
spring.servlet.multipart.max-file-size=20MB
# 沒有多文件上傳,也設定為20M
spring.servlet.multipart.max-request-size=20MB
# 語音的最大size B -> 10M
voice.max-size=10485760
# 視頻的最大size B -> 20M
video.max-size=20971520
# 圖片的最大size B -> 10M
image.max-size=10485760
扯回正題:以上的種種application.properties的配置參數,其實都可以通過java -jar的時候,以–開頭作為command的參數注入!(有些很長,當然如果你不嫌麻煩的話)
一般我們前台運行springboot的jar包的時候:
java -jar xxx.jar
加參數,例如修改server.port:
java -jar xx.jar --server.port=8888
設置運行的模式文件(dev等,這樣就能兩套文件外部運行的時候選擇了,比如正式部署的和運行的區別:開不開頁面緩存,設不設置sql打印輸出…)
java -jar xxx.jar --spring.profiles.active=dev
作者還額外提到可以通過:SpringApplication.setAddCommandLineProperties(false)禁用command注入,來規避風險。
作者還有提到,SpringBoot獲得配置屬性的多種途徑(學習,摘我知道的):
1.剛剛的命令參數
2.SPRING_APPLICATION_JSON中的屬性(環境變量或系統屬性中的內聯JSON嵌入)。
3.操作系統環境變量
4.應用程序以外的application.properties或者appliaction.yml文件(后面補充細講)
5.打包在應用程序內的application.properties或者appliaction.yml文件
6.默認屬性(通過SpringApplication.setDefaultProperties指定)例如application-dev.properties和application-test.properties
7.在需要注入的類上寫@PropertySource標注的屬性源(@PropertySource不止能加載項目類的噢,還能加載其它地方的):@PropertySource(“file://application.properties”) file代表協議,http,ftp,你也可以寫當前計算機系統下的全路徑訪問的文件。
以上還有問題,如果最終運行需要調整的參數多,上面的就不好用了!那怎么辦呢?
部署時在jar包同級目錄加上config文件夾,里面放入寫好了部署參數配置的application.properties
參照node2017的博文:
spring boot允許你自定義一個application.properties文件,然后放在以下的地方,來重寫spring boot的環境變量或者定義你自己環境變量(優先級同樣是先config,再當前,適合在生產環境下部署時使用)
1.當前目錄的 “/config”的子目錄下
2.當前目錄下
以上就是我對注入application.properties,以及SpringBoot中用好properties文件的全部了解