有没有一种干净的方法可以使用@ConfigurationProperties从application.properties中提取嵌套属性?

时间:2020-11-05 14:39:44

标签: java spring spring-boot properties spring-properties

我之所以寻求从@Value注释转移到使用@ConfigurationProperties主要是因为我最终拥有太多的属性,因此将所有属性添加到目标类中似乎会使该类带有Value注释和如果我将它们标记为final,则构造函数将具有一长串参数。

application.properties

sms-gateway:
  sms:
    authorization:
      token: xyz
    username: abc
    password: pass
    url: http://example.com
    lynx:
      cmd: lynx -dump -display_charset=utf-8 <%= @sms-gateway_sms_url %>
    via:
      cmd: true
  admin:
    status:
      url: http://admin.example.com/status

SmsService.java

...

@Value("${sms-gateway.sms.url}")
private String url;

@Value("${sms-gateway.sms.username}")
private String username;

@Value("${sms-gateway.sms.password}")
private String password;

and so on ...

作为备用@ConfigurationProperties,您可以拥有一个将属性分组在一起的专用类。但是,您最终将其绑定到公共命名空间,以使属性绑定到用@ConfigurationProperties注释的类的字段。

SmsConfig.java

...

@Getter
@RequiredArgsConstructor
@Configuration
@ConfigurationProperties(prefix = "sms-gateway.sms")
public class SmsConfig.java {
  
  private final String username;
  private final String password;
  private final String url;
  ...
}

但是,要添加其他嵌套属性,则需要为每个嵌套属性以及@NestedConfigurationProperty添加类,以表明这是一个嵌套属性。如果有许多嵌套的属性,这可能会再次失控。

我的问题有两个方面-

  1. 是否有一种更干净的方法来实现此目的,而不必涉及内部类并将绑定的属性绑定到同一公共名称空间中的字段下。 例如,在上面的示例中-我们如何绑定授权令牌或lynx命令属性而不必添加单个字段内部或全新的类。

  2. 是否可以更改字段名称并将其绑定到属性名称,所以说是否要使用其他名称private final String SmsGatewayUsername并将其绑定到username属性?

感谢您的任何评论和回答!

1 个答案:

答案 0 :(得分:0)

  1. 否,您不能更改结构。但是,如果您不介意丢失bean类型,则可以绑定Map<String, Object>

  2. 属性受bean属性的约束,bean属性由公共获取程序和设置程序(而不是字段名称)确定。您可以添加自己喜欢的任何名称的设置器,并在其中添加任何逻辑。要变得非常复杂,您可以编写一个自定义bean属性绑定器,但是我不建议在您的用例中使用它。默认的功能是将kebab-case转换为camelCase。

您的属性名称和配置类均应遵循逻辑结构,如果结构相同,则处理起来会容易得多。