是否可以使 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
此外,我已经通过插件来实现用例,并且有一些有用的插件可以将属性转换为 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
构建目录中)。
你可以打开它看看它是什么样子的。
关于这个过程的几点说明:
- 因为它发生在编译过程中 - 它不会查看
application.yaml
- 生成的 JSON 通常不会在运行时由 spring 引导本身使用,而是用于 IDE,以便它们可以构建一些漂亮的集成。这就是 IntelliJ 基本上所做的。
现在,IntelliJ(仅限终极版,因为社区版不包含与 spring 的任何集成)确实可以读取此文件,并提供一些自动完成功能。
但是 根据包含映射的配置属性中提供的信息 注释处理器(在编译期间再次运行并且只能访问 class ) 例如不能生成正确的键值。因此 IntelliJ 不会让您从 key1
、key2
中进行选择,因为它们不存在于配置属性 java 文件中。这就是为什么它不起作用。
归根结底,IntelliJ 并没有犯错,它已尽其所能 :)
分辨率方面:
您可以尝试两条路径:
不使用字符串作为键,使用枚举。由于它将具有一组有限且定义明确的值,因此注释处理器可能会生成更好的json(如果不是-它是注释处理器中的错误,或者更确切地说是增强请求)
假设注解处理器尽其所能,但并不总是成功,您可以按照 Spring Boot Documentation
[ 中所述手动定义 json
重现问题的源代码: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
此外,我已经通过插件来实现用例,并且有一些有用的插件可以将属性转换为 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
构建目录中)。
你可以打开它看看它是什么样子的。
关于这个过程的几点说明:
- 因为它发生在编译过程中 - 它不会查看
application.yaml
- 生成的 JSON 通常不会在运行时由 spring 引导本身使用,而是用于 IDE,以便它们可以构建一些漂亮的集成。这就是 IntelliJ 基本上所做的。
现在,IntelliJ(仅限终极版,因为社区版不包含与 spring 的任何集成)确实可以读取此文件,并提供一些自动完成功能。
但是 根据包含映射的配置属性中提供的信息 注释处理器(在编译期间再次运行并且只能访问 class ) 例如不能生成正确的键值。因此 IntelliJ 不会让您从 key1
、key2
中进行选择,因为它们不存在于配置属性 java 文件中。这就是为什么它不起作用。
归根结底,IntelliJ 并没有犯错,它已尽其所能 :)
分辨率方面:
您可以尝试两条路径:
不使用字符串作为键,使用枚举。由于它将具有一组有限且定义明确的值,因此注释处理器可能会生成更好的json(如果不是-它是注释处理器中的错误,或者更确切地说是增强请求)
假设注解处理器尽其所能,但并不总是成功,您可以按照 Spring Boot Documentation
[ 中所述手动定义 json