是否可以使 Spring 引导配置处理器正确处理值是复杂结构的映射(在 Intellij IDEA 中)?

Is it possible to make Spring Boot Configuration Processor work correctly with maps which values are complex structures (in Intellij IDEA)?

重现问题的源代码:link

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

    @Data
    @ConfigurationProperties(prefix = "props")
    public class ConfigProperties {

        private String testString;
        private Map<String, InnerConfigProperties> testMap;
    }
    @Data
    public class InnerConfigProperties {

        private String innerString;
        private Integer innerInt;
    }

application.yml中我是这样设置的:

props:
  testString: asdadasd
  somWrongProperty: asdasd
  testMap:
    key1:
      innerString: value1
      innerInt: 1
      someInnerWrongProperty: wrongvalue
    key2:
      innerString: value2
      innerInt: 2

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

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

IDEA 截图:

有人知道如何让它正常工作吗?请随意使用随附的示例代码。

提前致谢。

根据当前 documentation for auto-completing-code没有 IntelliJ IDEA 会建议您使用下一个可能的键并通知您不正确的值,例如 [=] 34=]somWrongProperty 或 someInnerWrongProperty

对于上述 用例,我发现有点相关且有用的是Expand a string at caret to一个现有的词

  • Press Alt+/ or choose Code | Completion | Cyclic Expand Word to search for matching words before the caret.

  • Press Shift+Alt+/ or choose Code | Completion | Cyclic Expand Word (Backward) to search for matching words after the caret and in other open files.


Code Style. YAML 我们可以如下自定义 YAML 的代码样式,但是上面的用例没有自动完成和错误的选项

文件 |设置 |编辑|代码风格 | Windows 和 Linux
的 YAML IntelliJ IDEA |偏好 |编辑|代码风格 |适用于 macOS 的 YAML Ctrl+Alt+S


Plugins

此外,我已经通过插件来实现用例,并且有一些有用的插件可以将属性转换为 yaml 但与用例无关。您可能需要等待或创建类似类型的插件。您可能会发现 this 有帮助

我相信你问的是添加的

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

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

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

关于这个过程的几点说明:

  1. 因为它发生在编译过程中 - 它不会查看 application.yaml
  2. 生成的 JSON 通常不会在运行时由 spring 引导本身使用,而是用于 IDE,以便它们可以构建一些漂亮的集成。这就是 IntelliJ 基本上所做的。

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

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

分辨率方面:

您可以尝试两条路径:

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

  2. 假设注解处理器尽其所能,但并不总是成功,您可以按照 Spring Boot Documentation

    [ 中所述手动定义 json