SpringBoot松散綁定/寬松綁定(Relaxed Binding)的實(shí)現(xiàn)
一、前言
在 Java 的配置文件中(如 .properties 和 .yml/.yaml),你看到駝峰命名(如 myProperty)和中劃線命名(如 my-property)同時(shí)有效,主要是因?yàn)?Spring Boot 的“寬松綁定”(Relaxed Binding)策略。
以mybatis的屬性配置為例
application.yml文件
# mybatis屬性配置 mybatis: configuration: map-underscore-to-camel-case: true # 開(kāi)啟下劃線轉(zhuǎn)駝峰的映射
application.properties文件
# mybatis屬性配置 mybatis.configuration.mapUnderscoreToCamelCase: true # 開(kāi)啟下劃線轉(zhuǎn)駝峰的映射
二、寬松綁定
2.1、何為寬松綁定
簡(jiǎn)單來(lái)說(shuō),寬松綁定是 Spring Boot 提供的一種智能屬性綁定機(jī)制。它允許你在配置屬性(如 application.properties、application.yml、環(huán)境變量、命令行參數(shù))中使用多種不同格式的名稱(chēng),Spring Boot 都能自動(dòng)將它們匹配到你的 @ConfigurationProperties
類(lèi)或 Bean
的對(duì)應(yīng)字段上。
Spring Boot 1.x 版本已初步支持寬松綁定,Spring Boot 2.x 版本進(jìn)一步強(qiáng)化了寬松綁定的規(guī)范性和一致性。新項(xiàng)目建議直接采用 Spring Boot 2.x + @ConfigurationProperties 以保障兼容性。
- @ConfigurationProperties 成為官方推薦方式 :明確僅通過(guò)此注解支持完整的寬松綁定規(guī)則(如前綴命名需符合 kebab-case 格式)。
- @Value 的局限性被固化: 雖然部分簡(jiǎn)單場(chǎng)景下 @Value 可能兼容寬松格式(如環(huán)境變量轉(zhuǎn)小寫(xiě)匹配),但官方文檔始終強(qiáng)調(diào)其不支持正式寬松綁定,未來(lái)版本可能調(diào)整此行為。
2.2、寬松綁定的規(guī)則
Spring Boot 支持以下幾種屬性命名格式的自動(dòng)轉(zhuǎn)換:
- 駝峰命名法(myProperty)
- 短橫線命名法(my-property)
- 下劃線命名法(my_property)
- 大寫(xiě)下劃線命名法(MY_PROPERTY)
2.3、寬松綁定規(guī)則詳解
Spring Boot 在匹配時(shí),會(huì)將配置源(文件、環(huán)境變量等)中的屬性名和 Java Bean 屬性名都進(jìn)行規(guī)范化處理:
- 將所有字符轉(zhuǎn)換為小寫(xiě)。
- 移除所有分隔符(-, _, 空格)。
- 比較規(guī)范化后的結(jié)果。
示例:
Java Bean 屬性名 | 有效的配置文件/YAML 屬性名示例 | 規(guī)范化后結(jié)果 (小寫(xiě), 無(wú)分隔符) |
---|---|---|
userName | userName (駝峰) | username |
user-name (中劃線 - 推薦) | username | |
user_name (下劃線) | username | |
USER_NAME (環(huán)境變量風(fēng)格 - 大寫(xiě)+下劃線) | username | |
server.port | server.port (點(diǎn)分隔) | server.port (點(diǎn)保留) |
server-port (不推薦,但寬松綁定可能允許) | serverport (可能出錯(cuò)!) |
重要提示: 對(duì)于帶 . 的層級(jí)屬性(如 server.port),使用中劃線替代點(diǎn)(server-port)通常不是好主意,也不推薦。 雖然寬松綁定在簡(jiǎn)單情況下可能“碰巧”工作(規(guī)范化后 serverport 與 server.port 的規(guī)范化形式 server.port 不同),但它破壞了屬性的層次結(jié)構(gòu),可能導(dǎo)致意外的綁定結(jié)果或錯(cuò)誤。點(diǎn) . 是表示配置樹(shù)層次結(jié)構(gòu)的標(biāo)準(zhǔn)和推薦方式。
總結(jié):
松散綁定就是在進(jìn)行匹配時(shí),配置中的名稱(chēng)要去掉中劃線和下劃線后,忽略大小寫(xiě)的情況下去與java代碼中的屬性名進(jìn)行忽略大小寫(xiě)的等值匹配
2.4、優(yōu)先級(jí)規(guī)則
如果同一屬性以不同格式多次配置,Spring Boot 按以下優(yōu)先級(jí)綁定:
- 精確匹配(字段名與配置名完全一致)。
- 短橫線命名法。
- 下劃線命名法。
- 大寫(xiě)下劃線命名法。
2.5、注意事項(xiàng)
在SpringBoot官方文檔中有幾個(gè)注意點(diǎn):
- 屬性必須要有g(shù)etter、setter方法;
- 如果屬性的類(lèi)型是集合,要確保集合是不可變的;
- 如果使用Lombok自動(dòng)生成getter/setter方法,一定不要生成對(duì)應(yīng)的任何構(gòu)造函數(shù),因?yàn)镾pring IOC容器會(huì)自動(dòng)使用它來(lái)實(shí)例化對(duì)象。
- 使用JavaBean屬性綁定的方式只針對(duì)標(biāo)準(zhǔn) Java Bean 屬性,不支持對(duì)靜態(tài)屬性的綁定。
- 前綴匹配: @ConfigurationProperties 的 prefix 也支持寬松綁定。例如,prefix = “my-app” 可以匹配 myApp、my_app 等。
- 嚴(yán)格模式: 可以通過(guò)
spring.boot.configurationprocessor.strict
啟用嚴(yán)格模式,禁用寬松綁定。
三、寬松綁定實(shí)例
3.1、@ConfigurationProperties注解與寬松綁定
application.yml
user: userName: 張三 # 駝峰命名 user-age: 11 # 中劃線 user_class: 三年級(jí)二班 # 下劃線 USER_SEX: 男 # 大寫(xiě)+下劃線
UserConfig.java
package com.demo.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "user") @Data public class UserConfig { private String userName; private int userAge; private String userClass; private String userSex; }
TestController.java
package com.demo.controller; import com.demo.config.UserConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "test") public class TestController { @Autowired UserConfig userConfig; @Value("${user.userage}") private String userage; @GetMapping("") public String test(){ System.out.println(userConfig); return userConfig.toString(); } }
四、其他問(wèn)題
4.1、Spring Boot Configuration Annotation Processor not configured
問(wèn)題描述: 當(dāng)我們使用@ConfigurationProperties注解進(jìn)行屬性注入時(shí),配置類(lèi)上面可能會(huì)顯示Spring Boot Configuration Annotation Processor not configured
解決方法:
在pom.xml中引入一下依賴(lài)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
該依賴(lài)的作用,簡(jiǎn)單來(lái)說(shuō)就是為自定義的配置類(lèi)生成元數(shù)據(jù)信息。然后報(bào)錯(cuò)問(wèn)題解決,文件能夠正常使用。
五、總結(jié)
注意:
- ConfigurationProperties的prefix的值必須是短橫線隔開(kāi)式,如demo.relaxed-binding
- @ConfigurationProperties注解支持全量的屬性 寬松綁定方式;而@Value只推薦使用標(biāo)準(zhǔn)的kebab-case方式(僅使用小寫(xiě)字母和-),例如:@Value(“{demo.item-price}”)可以提取demo.item-price和demo.itemPrice。
- 松散綁定就是在進(jìn)行匹配時(shí),配置中的名稱(chēng)要去掉中劃線和下劃線后,忽略大小寫(xiě)的情況下去與java代碼中的屬性名進(jìn)行忽略大小寫(xiě)的等值匹配
到此這篇關(guān)于SpringBoot松散綁定/寬松綁定(Relaxed Binding)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot松散綁定/寬松綁定內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java基本教程之java線程等待與java喚醒線程 java多線程教程
這篇文章主要介紹了對(duì)線程等待/喚醒方法,文中使用了多個(gè)示例,大家參考使用吧2014-01-01詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì)
這篇文章主要介紹了詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Spring BeanPostProcessor接口使用詳解
本篇文章主要介紹了Spring BeanPostProcessor接口使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01面試JAVA時(shí),問(wèn)到spring該怎么回答
這篇文章主要介紹了Spring面試資料,學(xué)Java的小伙伴都知道Spring是面試的必問(wèn)環(huán)節(jié),看完了一天就可掌握數(shù)據(jù)結(jié)構(gòu)和算法的面試題,快來(lái)看看吧2021-08-08MyBatis新增數(shù)據(jù)時(shí)自增id的兩種寫(xiě)法小結(jié)
本文介紹了在MyBatis中配置自增ID的兩種方法:一種是通過(guò)在Mapper文件中設(shè)置useGeneratedKeys和keyProperty,另一種是使用selectKey標(biāo)簽,批量插入時(shí),同樣采用useGeneratedKeys標(biāo)簽,感興趣的可以了解一下2024-09-09Java的異常體系以及File類(lèi)構(gòu)造方法詳解
這篇文章主要為大家介紹了Java的異常體系以及File類(lèi)構(gòu)造方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05SpringBoot解析指定Yaml配置文件的實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了SpringBoot解析指定Yaml配置文件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03