Spring Boot 2.0.0.RELEASE嵌套配置属性绑定失败,如何指定前缀?
解决Spring Boot嵌套配置属性绑定为null的问题
你遇到的问题核心是Spring Boot的@ConfigurationProperties绑定规则:它默认是根据字段名称(而非内部类名称)来匹配配置文件中的key,同时遵循JavaBean的getter/setter命名规范。
你的代码里,PersonProperties中的字段是addressProperties,Spring Boot会默认去匹配配置里的person.addressProperties路径,但你在yml里写的是person.address,自然匹配不上,导致addressProperties始终为null。下面给你几个可行的解决方案:
方案1:使用@JsonProperty指定配置映射的key
这是最简洁的方法,不需要修改字段名或类结构,只需要在addressProperties字段上添加@JsonProperty("address"),明确告诉Spring Boot这个字段对应配置中的address键:
@Configuration @ConfigurationProperties(prefix="person") public class PersonProperties { @JsonProperty("address") private AddressProperties addressProperties; public AddressProperties getAddressProperties() { return addressProperties; } public void setAddressProperties(final AddressProperties addressProperties) { this.addressProperties = addressProperties; } public static class AddressProperties { private String line1; public String getLine1() { return line1; } public void setLine1(final String line1) { this.line1 = line1; } } }
方案2:修改字段名与配置key一致
这是你已经尝试过的有效方法,把字段名从addressProperties改成address,让它和yml里的addresskey直接匹配:
@Configuration @ConfigurationProperties(prefix="person") public class PersonProperties { private AddressProperties address; // 字段名改为address public AddressProperties getAddress() { // getter对应字段名 return address; } public void setAddress(final AddressProperties address) { // setter对应字段名 this.address = address; } public static class AddressProperties { private String line1; public String getLine1() { return line1; } public void setLine1(final String line1) { this.line1 = line1; } } }
方案3:将嵌套类注册为独立的配置Bean
如果你希望保留原有的字段名和类名,也可以把AddressProperties单独注册为配置Bean,指定它的前缀为person.address,然后注入到PersonProperties中:
@Configuration @ConfigurationProperties(prefix="person") public class PersonProperties { private AddressProperties addressProperties; // 通过构造注入或者@Autowired注入 @Autowired public PersonProperties(AddressProperties addressProperties) { this.addressProperties = addressProperties; } // getter和setter } @ConfigurationProperties(prefix = "person.address") @Component public class AddressProperties { private String line1; // getter和setter }
如果想保持AddressProperties为内部类,也可以这样写:
@Configuration @ConfigurationProperties(prefix="person") public class PersonProperties { private AddressProperties addressProperties; @Autowired public void setAddressProperties(AddressProperties addressProperties) { this.addressProperties = addressProperties; } // getter @ConfigurationProperties(prefix = "person.address") @Component public static class AddressProperties { private String line1; // getter和setter } }
以上几种方法都能解决你的属性绑定问题,推荐优先使用方案1或方案2,代码更简洁直观。
内容的提问来源于stack exchange,提问作者ByeBye
相关产品推荐
相关产品推荐

