1. 程式人生 > >SpringBoot2.x升級踩坑--新增Configuration property name限制

SpringBoot2.x升級踩坑--新增Configuration property name限制

最近公司專案在做SpringBoot的升級,在升級過程中遇到了一些問題,簡單記錄一下,做個分享。另外,本文中的程式只為示例程式碼,並非公司生產環境程式碼。

遇到什麼問題

從SpringBoot1.x升級到SpringBoot2.x之後,解決完編譯異常,執行程式,在程式啟動時報錯:

報錯資訊就已經很直白的告訴了我們錯誤原因:

配置屬性名稱“com_shen”無效

無效字元: '_', 原因:規範名稱應為kebab-case(用'-'分隔),小寫字母數字字元,並且必須以字母開頭

怎麼解決

經過排查,是因為在application.properties檔案中有如下一個配置項:

com_shen.name=xiaohei

對應Java程式程式碼:

@Getter
@Setter
@ConfigurationProperties(prefix = "com_shen")
public class Service {
    private String name;
}

結合報錯日誌,我們可以很容易的解決這個問題,去掉配置項中的_,將配置項name修改為com.shen.name即可。

原始碼解析

你以為文章寫到這裡就結束了嗎?其實並沒有。hhhhhh,通過這個問題,我們來看一下SpringBoot2.x的內部原始碼。什麼,你不知道該從哪裡入手來看這個原始碼,沒關係,我們一步一步來。

點開@ConfigurationProperties

原始碼,

在Spring中,大量的功能都是通過BeanPostProcessor來實現的。而且,Spring中的原始碼註釋寫的非常的仔細。通過原始碼註釋我們可以猜到可能是ConfigurationPropertiesBindingPostProcessor這個類在負責@ConfigurationProperties註解的背後支援。

點開ConfigurationPropertiesBindingPostProcessor類原始碼,發現在該類中Override了BeanPostProcessorpostProcessBeforeInitialization方法:

在這個方法中,呼叫了bind(bean, beanName, annotation);

方法。這個方法名叫"繫結",方法中傳入了bean、beanName和annotation的資訊,經驗告訴我這個方法大概率就是在負責解析@ConfigurationProperties,進行屬性繫結。

於是,在這裡打一個條件斷點,debug執行專案:

通過debug發現的確是這個方法在進行屬性繫結。而且底層呼叫了org.springframework.boot.context.properties.bind.Binder#bind(String, Bindable<T>, BindHandler) 方法:

在這個bind方法中,又呼叫了另一個方法bind(ConfigurationPropertyName.of(name), target, handler);,而且通過name生成了ConfigurationPropertyName物件ConfigurationPropertyName.of(name),通過方法名我們可以猜測,這個方法可能是在負責解析Configuration Property Name,專案啟動的報錯資訊很有可能是這個方法中丟擲的。點開原始碼:

發現在這個方法中,呼叫了InvalidConfigurationPropertyNameException.throwIfHasInvalidChars(name,ElementValidator.getInvalidChars(elementValue));。Spring程式碼命名真的是太優雅了,雖然名稱很長,但是讓原始碼閱讀者一看就能明白這個方法在做什麼。

通過原始碼,我們可以看到,在SpringBoot中對Configuration property name中的字元進行了有效性的判斷,判斷規則如上圖所示。

ElementValidator類是ConfigurationPropertyName的一個內部類。ConfigurationPropertyName是SpringBoot2.0新增的一個類,讓我們一起來閱讀一下類中註釋,瞭解一下這個類:

機器翻譯結果如下:

由點分隔的元素組成的配置屬性名稱。 使用者建立的名稱可以包含字元“ a-z”,“ 0-9”)和“-”,它們必須為小寫字母,並且必須以字母數字字元開頭。 “-”僅用於格式化,即“ foo-bar”和“ foobar”被認為是等效的。
“ [”和“]”字元可用於表示關聯索引(即Map鍵或Collection索引。索引名稱不受限制,並且區分大小寫。

以下是一些典型示例:

spring.main.banner-mode
server.hosts [0]。名稱
日誌[org.springboot] .level

使用@Value

我們知道,SpringBoot中除了可以使用@ConfigurationProperties之外,還可以使用@Value

Demo程式如下:

@Getter
@Setter
@Component
public class Service {

    @Value("${com_shen.name}")
    private String name;
}

application.properties檔案:

com_shen.name=xiaohei

在這種情況下,專案依舊啟動成功了,而且成功的獲取到了com_shen.name的屬性值。也就是說,@Value註解中並沒有表示式做限制。

拓展閱讀

Property Binding in Spring Boot 2.0 : https://spring.io/blog/2018/03/28/property-binding-in-spring-boot-2-0


歡迎關注公眾號,大家一起學習成長。

相關推薦

SpringBoot2.x升級--新增Configuration property name限制

最近公司專案在做SpringBoot的升級,在升級過程中遇到了一些問題,簡單記錄一下,做個分享。另外,本文中的程式只為示例程式碼,並非公司生產環境程式碼。 遇到什麼問題 從SpringBoot1.x升級到SpringBoot2.x之後,解決完編譯異常,執行程式,在程式啟動時報錯: 報錯資訊就已經很直白的告

jQuery升級 ---Cannot read property 'mise' of undefined

版本 兩種 文件 tor www. query read ise navig 同學今天發了條信息問我:‘“你有沒有遇到 query1.9以後的版本替代1.9以前的版本 使用jQuery migrate插件無效的問題啊???” 我:

jQuery版本升級大全

比較 錯誤 ron 相差 源碼 true -m tro 經驗 背景 -------------------------------------------------------------------------------- jQuery想必各個web工程師都再熟悉不

Android Rxjava2升級()筆記

Rxjava2 升級(踩坑)筆記 前言 最近接觸到別人程式碼的時候看到他們RxJava寫的和我的不一樣。Single、Completable、Disposable 什麼不知道,CompositeDisposable這又是什麼鬼??doAfterTerminate()這個方法好可以再事

async語法升級小記

從今年過完年回來,三月份開始,就一直在做重構相關的事情。 就在今天剛剛上線了最新一次的重構程式碼,希望高峰期安好,接近半年的Node.js程式碼重構。 包含從callback+async.waterfall到generator+co,統統升級為了async,還順帶推動了TypeScript在我司的使用。 這

18.04 作死升級

最近正好專案空閒期,看到系統推送之後突然腦抽,明明深知知“升級系統搞幾天”這條真理我還是毅然決然地作死點了升級。。 果不其然,自動升級彈出失敗彈窗。。。 升級失敗 1. 升級失敗     沒辦法,根據經驗,這個時候要不就再試一次,要不就回復之前系統,或者重啟試

React-Native版本升級

由於xcode更新到8,React-Native版本低於0.32的在xcode8中執行選擇模擬的系統小於IOS9.3會報錯,打包出來的版本在安裝時IOS系統低於9.3,執行時會崩潰。由於我目前使用的是react-native的版本是0.23,諮詢過faceboo

MyBatis升級

前段時間,偶然發現系統某核心模組使用for迴圈插入資料,遂想進行優化,一次批量插入是個不錯的方案,可能可以提高插入速度,肯定可以節約資料庫連線。系統用ORM框架MyBatis做DAO,考慮用MyBatis自帶批量提交功能實現,so easy對吧,但接下來坑一個接

】angularJS 1.X版本中 ng-bind 指令多空格展示

ext 數據庫查詢 sci 接收 可能 color 最終 數據 目的 做項目的時候遇到的問題 1、問題描述   用戶在表單某個值輸入多個空格,例如:A B,保存至服務器   在列表查詢頁面中使用bg-bind的指令單向綁定,結果展示位A B,連續的空格被替換

Vue2.x與總結

vue2.x 1.獨立構建vs執行時構建 在按照vue1.0的配置配置好webpack後,會出現Failed to mount component: template or render function not defined. (found in root instance) 的錯誤,這裡涉

RISC-V記----__builtin_clz((x)庫函式的應用

  RISC-V的確是個好東西,可是,免費的東西往往需要付出代價才能得到了,最近遇到了一個演算法中的問題,追了好久,最終追到了這個庫函式中,沒想到,這個庫函式居然還隱藏著一些貓膩。值得記下來啊。 首先上一個在X86平臺下的例子:    1 #include <stdio.h>

Springboot2.x+shiro+redis整合填 (一)redis只做快取的情況 Springboot2.0 整合shiro許可權管理

主要記錄關鍵和有坑的地方 前提: 1、SpringBoot+shiro已經整合完畢,如果沒有整合,先查閱之前的Springboot2.0 整合shiro許可權管理 2、redis已經安裝完成 3、redis客戶端使用Lettuce,這也是sprinboot2.0後預設的,與jedis的區別,自行百度

【java學習筆記】記錄,異常:javax.el.PropertyNotFoundException: Property [XXX] not found on type [XXX.XXX.XXX.XXX]

練習JavaWeb專案時,報錯javax.el.PropertyNotFoundException,原因是EL表示式裡面的屬性和pojo裡面的屬性名字沒有對上,範了個低階錯誤。 jsp中: <li>歡迎您,${loginUser.username}!</li> pojo

升級Gradle4.6

最近AS提示工程可升級gradle4.6,com.android.tools.build:gradle:3.2.1 根據提示升級了,但是發現怎麼也編譯不過去了,clean,刪build資料夾 各種不行。就是找不到androidannotations沒有生成帶"_"的類。 於是google

Activiti6.0記錄(一)-用admin登入後臺配置終端提示“Endpoint configuration for 'Activiti app' is invalid”

最近主管需要我搭建一個基於Activiti6.0引擎的工作流平臺,在配置好Tomcat併成功執行Activiti6.0官網所提供的war包後,在平臺上建立了一個二級審批流程,整個流程結束以後,需要用admin賬號去activiti-admin管理平臺檢視這個流程審批情況。 在登入介面輸入 使用者

vue-cli3.x 新特性及

前言 Webpack 是一個現代 JavaScript 應用程式的模組打包器 (module bundler) 。當 Webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖,其中包含應用程式需要的每個模組,然後將所有這些模組打包成少量的 bundle - 通

Spring Security 4.x -> 5.x 記錄

1. AuthenticationManager無法自動注入 在實現AbstractAuthenticationProcessingFilter重寫以使用者名稱、密碼認證時,需要顯示注入AuthenticationManager,不然會報如下錯誤: Caus

ElasticSearch5.x記錄(一):windows系統下的ElasticSearch5.6.3及head外掛安裝

 之前用es2.x版本做過一個檢索系統,隨著公司業務的發展,資料量也越來越大,現在準備採用es叢集的方式加快檢索速度,提高使用者的使用體驗。找到es的官網竟然發現版本已經到了5.63,天啦嚕,這發展是不是太快了點!稍後瞭解了下才明白,es只不過是為了版本統一而將版本號提升到了

Springboot2.x+shiro+redis整合填 (一)redis只做快取的情況

主要記錄關鍵和有坑的地方 前提: 1、SpringBoot+shiro已經整合完畢,如果沒有整合,先查閱之前的Springboot2.0 整合shiro許可權管理 2、redis已經安裝完成 3、redis客戶端使用Lettuce,這也是sprinboot2.0後預設的,與jedis的區別,自行百度 4、js

升級PHP7!~~~

之前就聽說php7這個版本有很大的提升,終於公司的專案也要升級到PHP7了。 升級之前看了一下大家整理好的一些介紹,發現這個版本是從底層開始就有很大的更改,當然,效率也提升了很多。 除了一些新增的功能(這個大家都已經寫的很全了,寫一些我沒看到的,隨著專案的踩坑慢