在Spring本地构建中使用带Map的Properties类

zpgglvta  于 2023-01-12  发布在  Spring
关注(0)|答案(1)|浏览(122)

我尝试使用GraalVM和Spring Boot 3.0构建一个本机可执行文件。
当我使用包含HashMap的配置属性类时,这些应用程序的启动失败。
example project
这个类包含一个简单的Map:

@Validated
@Data
@Component
@ConfigurationProperties(prefix = "test-props")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TestProperties {

    @NotEmpty
    HashMap<String, PermissionsConfig> datagroups;

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @FieldDefaults(level = AccessLevel.PRIVATE)
    public static class PermissionsConfig {
      // fields
    }
}

配置:

test-props:
  datagroups:
    data:
      read:
        code: READ_DATA
        urlPattern:
          - /some/pattern/

使用此小型测试运行程序:

@Slf4j
@Component
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class TestRunner implements ApplicationRunner {

    TestProperties testProperties;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        if (testProperties.getDatagroups() == null) {
            throw new RuntimeException("property not binded");
        }

        log.info("property {}", testProperties);

    }
}

作为"普通" Java应用程序启动此应用程序,一切正常。当我构建本机可执行文件时,我遇到以下问题:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'test-props' to test.properties.TestProperties failed:
    Property: test-props.datagroups
    Value: "null"

我还尝试为属性类添加额外的提示,在添加这些提示之前,验证根本不起作用。
我希望这也能在本机映像中工作。
我监督了什么?
重现步骤:

qkf9rpyu

qkf9rpyu1#

我自己解决了这个问题。它不是Lombok或所有注解。我删除了它(但也用所有注解测试了它)。在我的示例中,AOT编译器无法检测Map中使用的子类。添加所有这些子类作为提示可以使它工作。

public class TestHints implements RuntimeHintsRegistrar {
    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        addAll(hints, TestProperties.class);
        addAll(hints, TestProperties.PermissionsConfig.class);
        addAll(hints, TestProperties.Permission.class);

    }
 }

另请参见issue on spring boot project
更新:
除了添加提示外,还可以将@NestedConfigurationProperty用于 * 权限读取 * 和 * 权限历史 * 字段。
由于Permission对象未在 * PermissionConfig * 中定义,因此它是嵌套对象。将类定义移到 * PermissionConfig * 类中也可以

相关问题