【问题标题】:@ConfigurationProperties Set<Type>@ConfigurationProperties 设置<类型>
【发布时间】:2019-12-21 21:26:14
【问题描述】:

我希望在启动时加载一些属性并将它们转换为正确的类型。

application.yml:

base:
  security:

    scopes:
      - name: read
        descripton: read some nice things

      - name: write
        description: write some nice things

    authorities:
      - name: ROLE_ADMIN
        scopes:
          - read
          - write

      - name: ROLE_USER
        scopes:
          - read 

为了将这些属性加载到类型中,我使用了以下@ConfigurationProperties: BaseProperties.java

@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix="base.security")
public class BaseProperties {

    private Set<ScopeProperty> scopes = new HashSet<>();
    private Set<AuthorityProperty> authorities = new HashSet<>();

    @Getter
    @Setter
    public class AuthorityProperty {
        private String name;
        private List<String> scopes;
    }

    @Getter
    @Setter
    public class ScopeProperty {
        private String name;
        private String description;
    }
}

我得到的一切都是一个 BindException,如下所示:

Caused by: org.springframework.boot.context.properties.bind.UnboundConfigurationPropertiesException: The elements [base.security.authorities[0].name,base.security.authorities[0].scopes[0],base.security.authorities[0].scopes[1],base.security.authorities[1].name,base.security.authorities[1].scopes[0]] were left unbound.
    at org.springframework.boot.context.properties.bind.IndexedElementsBinder.assertNoUnboundChildren(IndexedElementsBinder.java:136)
    at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:113)
    at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:86)
    at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:71)
    at org.springframework.boot.context.properties.bind.CollectionBinder.bindAggregate(CollectionBinder.java:49)
    at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:56)
    at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$2(Binder.java:293)
    at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:429)
    at org.springframework.boot.context.properties.bind.Binder$Context.access$100(Binder.java:372)
    at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:293)
    at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:254)
    at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:214)

解决方案:

将类标记为静态将它们创建为单独的类

    @Getter
    @Setter
    public static class AuthorityProperty {
        private String name;
        private List<String> scopes;
    }

    @Getter
    @Setter
    public static class ScopeProperty {
        private String name;
        private String description;
    }

【问题讨论】:

  • 使用 Delombok 以避免将来出现类似问题 :)
  • @Nikolas 为什么要在 2020 年使用 Lombok?是的,在 2012 年它很酷,但现在我们有了 Kotlin,无论如何问题出在类层次结构而不是属性中
  • 即使没有 lombok 也无法正常工作,同样的异常
  • @BorisTreukhov:我说的是“相似”,而不是“精确”。我没有检查问题的根源,但提出了一个提示。我不知道这个问题可能与龙目岛有关,也可能无关。作者试图在没有 Lombok 的情况下运行它,这意味着存在 可能性 Lombok 导致隐藏在后面的问题。然而,即使没有它是一个完全不同的故事,它仍然无法工作。
  • 谢谢你们俩 :-) 我在这个问题上浪费了几个小时。 :-D

标签: spring spring-boot property-binding


【解决方案1】:

您的类是内部类,需要构造外部类 BaseProperties 的实例,Spring Properties 不支持。

您可以使用关键字static 标记您的课程,这应该可以工作

@Getter
@Setter
public static class AuthorityProperty {
    private String name;
    private List<String> scopes;
}

【讨论】:

    【解决方案2】:

    我刚刚找出了这个问题的原因。 看来,spring 无法使用声明属性集类型的内部类来处理这个问题。 我将这些类提取到单独的类中,但它不起作用。

    【讨论】:

    • 太棒了,这行得通。谢谢你。即使是龙目岛。您能否将其发布为回复,然后我将其标记为已解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 2015-06-16
    • 2013-03-29
    相关资源
    最近更新 更多