
环境:Springboot2.4.12 准备环境@Component @ConfigurationProperties("pack") public class PackProperties { private boolean enabled; private InetAddress remoteAddress; private final Security security = new Security(); public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public InetAddress getRemoteAddress() { return remoteAddress; } public void setRemoteAddress(InetAddress remoteAddress) { this.remoteAddress = remoteAddress; } public Security getSecurity() { return security; } public static class Security { private String username; private String password; private Listroles = new ArrayList<>(Collections.singleton("USER")); public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public ListgetRoles() { return roles; } public void setRoles(Listroles) { this.roles = roles; } @Override public String toString() { return "Security [username=" + username + ",配置 password=" + password + ", roles=" + roles + ", " + roles.size() + "]"; } } @Override public String toString() { return "PackProperties [enabled=" + enabled + ", remoteAddress=" + remoteAddress + ", security=" + security + "]"; } }JavaBean属性绑定绑定一个声明标准JavaBean属性的bean。 pack: remote-address: 192.168.2.100 security: roles: GUEST,属性 ADMIN #List集合可用通过逗号`,`分割方式配置输出: PackProperties [enabled=false, remoteAddress=/192.168.2.100, security=Security [username=null, password=null, roles=[GUEST, ADMIN], 2]]根据上面的JavaBean定义属性说明: pack.enabled, 默认是为false。pack.remote-address,类型 自动从String转换为InetAddress。pack.security.username,安全 使用嵌套的“security”对象,该对象的都解名称由属性的名称确定。特别是配置,这里根本没有使用返回类型,属性可以使用SecurityProperties。类型pack.security.roles,安全 使用默认为USER的String集合。构造器绑定修改上面的都解PackProperties。 @Component @ConstructorBinding @ConfigurationProperties("pack") public class PackProperties { private boolean enabled; private InetAddress remoteAddress; private final Security security; public PackProperties(boolean enabled,配置 InetAddress remoteAddress, Security security) { this.enabled = enabled; this.remoteAddress = remoteAddress; this.security = security; } }在此设置中,@ConstructorBinding注释用于指示应使用构造函数绑定。属性这意味着绑定器将期望找到一个包含您希望绑定的类型参数的构造函数。 @ConstructorBinding类的安全嵌套成员(如上例中的Security)也将通过其构造函数进行绑定。 可以使用@DefaultValue指定默认值,都解并且应用相同的转换服务将String值强制转换为缺失属性的目标类型。默认情况下,如果没有属性绑定到Security, PackProperties实例将包含用于security 的 null值。云南idc服务商如果你希望返回一个非空的Security实例,即使没有属性绑定到它,你可以使用一个空的@DefaultValue注释来这样做: 如果只是上面那样配置,程序会报错,因为上面的PackProperties也是个Bean,并且只提供了一个有参数的构造函数,那么容器就会进行构造方法注入,从容器中查找参数类型的Bean进行注入,而容器当前是没有这些bean的,也就是说容器会吧构造函数中的参数以Bean的形式进行注入,并不会(也不知道)从配置文件中读取相关的值进行设置。通过如下方式可以实现构造函数的配置。 @ConfigurationPropertiesScan。修改属性配置类。 @ConstructorBinding @ConfigurationProperties("pack") public class PackProperties { }在启动类上添加注解。 @SpringBootApplication @ConfigurationPropertiesScan(basePackages = {"com.pack"}) public class SpringWebDemoApplication { }该种方式就可以实现构造函数的注入。 @EnableConfigurationProperties。该种方式也是高防服务器在一个配置类或者启动类上添加注解。 @SpringBootApplication @EnableConfigurationProperties(PackProperties.class) public class SpringWebDemoApplication { }Enabling @ConfigurationProperties-annotated typesSpring Boot提供了基础设施来绑定@ConfigurationProperties类型并将它们注册为bean。可以逐个类地启用配置属性,也可以启用与组件扫描方式类似的配置属性扫描。 有时,带有@ConfigurationProperties注释的类可能不适合扫描,例如,如果你正在开发自己的自动配置,或者希望有条件地启用它们。在这些情况下,使用 @EnableConfigurationProperties注释指定要处理的类型列表。这可以在任何 @Configuration类上完成,如下所示: @Configuration @EnableConfigurationProperties(PackProperties.class) public class PropConfig { }要使用配置属性扫描,请将 @ ConfigurationPropertiesScan注释添加到应用程序中。通常,它被添加到用@SpringBootApplication注释的主应用程序类中,但它也可以添加到任何@Configuration类中。默认情况下,扫描将从声明注释的类的包中进行。如果你想定义特定的包来扫描,你可以这样做,如下所示的例子: @SpringBootApplication @ConfigurationPropertiesScan({ "com.pack.app", "org.pack.another" }) public class MyApplication { }第三方配置除了使用@ConfigurationProperties来注释类之外,还可以在公共的@Bean方法上使用它。服务器托管当你希望将属性绑定到你无法控制的第三方组件时,这样做特别有用。 @ConfigurationProperties(prefix = "pack.third") @Bean public ThirdComponent thirdComponent() { return new ThirdComponent(); }在配置中配置的以pack.third为前缀的所有配置都将为JavaBean属性都被映射到ThirdComponent bean上。 @ConfigurationProperties验证Spring Boot尝试验证@ConfigurationProperties类,只要它们被Spring的@Validated注解注解。您可以使用JSR-303 javax.validation约束注释直接在配置类上。要做到这一点,请确保类路径上有一个符合JSR-303的实现,然后向字段添加约束注释,如下所示: @ConstructorBinding @ConfigurationProperties("pack") @Validated public class PackProperties { private boolean enabled; @NotNull(message = "请输入远程地址") private InetAddress remoteAddress; }注意:还需要确保环境中有JSR-303的实现,这里使用的Hidernate。 org.hibernate hibernate-validator 6.0.7.Final </dependency>如果没有配置remoteAddress,程序启动将会报错误。 Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under pack to com.pack.propsbinding.PackProperties failed: Property: pack.remoteAddress Value: null Reason: 请输入远程地址为了确保总是为嵌套属性触发验证,即使没有找到属性,关联字段必须用@Valid注释。下面的示例构建在前面的PackProperties示例之上: @Component @ConfigurationProperties("pack") @Validated public class PackProperties2 { private boolean enabled; @NotNull(message = "请输入远程地址") private InetAddress remoteAddress; @Valid private Security security = new Security() ; }进过测试结果验证与官方文档不一致?嵌套属性即便不加@Valid注解也是可以在嵌套对象中的属性添加验证一样会生效。 @ConfigurationProperties vs. @Value@Value注释是一个核心容器特性,它不提供与类型安全的配置属性相同的特性。下表总结了@ConfigurationProperties和@Value支持的特性: Feature @ConfigurationProperties @Value 宽松绑定 Yes Limited (see note below) 元数据支持 Yes No SpEL表达式 No Yes |