是否可以使 Spring Boot 配置处理器与值是复杂结构的映射正常工作(在 Intellij IDEA 中)?

ams*_*ger 7 java spring intellij-idea spring-boot configurationproperties

重现问题的源代码:链接

假设我有这种配置属性的结构:

    @Data
    @ConfigurationProperties(prefix = "props")
    public class ConfigProperties {
    
        private String testString;
        private Map<String, InnerConfigProperties> testMap;
    }
Run Code Online (Sandbox Code Playgroud)
    @Data
    public class InnerConfigProperties {
    
        private String innerString;
        private Integer innerInt;
    }
Run Code Online (Sandbox Code Playgroud)

application.yml我这样设置它们:

props:
  testString: asdadasd
  somWrongProperty: asdasd
  testMap:
    key1:
      innerString: value1
      innerInt: 1
      someInnerWrongProperty: wrongvalue
    key2:
      innerString: value2
      innerInt: 2
Run Code Online (Sandbox Code Playgroud)

启动注释处理后,只有简单的属性可以正常工作(您可以通过单击 导航到它们的声明ctrl,它们的自动完成也可以工作)。此外,IDEA 还会检测该属性是否不正确并突出显示它。

对于嵌套结构(即映射值),这两个功能似乎都无法正常工作。您仍然可以单击它们,但 IDEA 将导航到地图声明。此外,地图值的代码完成和错误字段的突出显示不起作用。

IDEA 截图:

在此输入图像描述

有谁知道如何使其正常工作?请随意使用随附的示例代码。

提前致谢。

更新

似乎已在 Intellij IDEA 2022.1 中修复。相关问题:IDEA-151708IDEA-159276

不过,修复错误的效率不错。

Mar*_*nik 3

我相信你问的是添加的

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
Run Code Online (Sandbox Code Playgroud)

这基本上是一个注释处理器 - 编译过程中的一个特殊挂钩,可以在编译时检测用某些注释注释的类,并根据该定义生成一些资源。一些注释处理器会生成其他源文件,但是这个处理器会内省通过@ConfigurationProperties反射注释的类,并根据此类中找到的字段名称和类型,它会生成一个特殊的 json 文件(META-INF/spring-configuration-metadata.jsontarget构建目录)。

你可以打开它,看看它是什么样子的。

现在关于此过程的一些注意事项:

  1. 因为它发生在编译期间 - 它不看application.yaml
  2. 一般来说,生成的 JSON 在运行时不会被 Spring Boot 本身使用,而是用于 IDE,以便它们可以构建一些漂亮的集成。这就是 IntelliJ 基本上所做的事情。

现在,IntelliJ(仅限终极版,因为社区版不包含与 spring 的任何集成)确实可以读取此文件,并提供一些自动完成功能。

但是,根据包含映射的配置属性中提供的信息,注释处理器(在编译期间再次运行并且只能访问该类)仅仅无法生成正确的键值。因此 IntelliJ 不会提供您从 , 中进行选择key1key2因为它们不存在于配置属性 java 文件中。这就是为什么它不起作用。底线是,IntelliJ 没有罪,它已经尽力了:)

从分辨率来看:

有两条路可以尝试:

  1. 不要使用字符串作为键,而是使用 enum。由于它将具有一组有限且定义良好的值,因此注释处理器可能会生成更好的 json (如果没有 - 它是注释处理器中的错误,或者更确切地说是增强的请求)

  2. 假设注释处理器尽了最大努力,但并不总是成功,您可以按照Spring Boot 文档中的描述手动定义 json