我们在引用spring官方start库或者第三方start库时,在写配置文件时idea总是能精准的提示,并且鼠标可以点过去看具体属性或者类,而自己写的配置文件idea只会有“Cannot resolve configuration property …”这样的提示。
我们现在也去配置我们自己的配置文件让idea知道这些配置文件是干什么的。

一、需要的注解

  • @ConfigurationProperties 配置属性文件,需要指定前缀 prefix
  • @EnableConfigurationProperties 启用配置,需要指定启用的配置类
  • @NestedConfigurationProperty 当一个类中引用了外部类,需要在该属性上加该注解

    二、POM依赖

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-configuration-processor</artifactId>
    4. <optional>true</optional>
    5. </dependency>
    6. 复制代码

    三、配置类

    1. @Data
    2. public class School {
    3. private Integer no;
    4. private String name;
    5. private String address;
    6. }
    7. 复制代码
    1. @Data
    2. @ConfigurationProperties(prefix = "jiuxian")
    3. public class JiuxianProperties {
    4. private String name;
    5. private String nameCn;
    6. private String nameEn;
    7. private String[] hobbies;
    8. private SexEnum sexEnum;
    9. private boolean single;
    10. private School school;
    11. private City city;
    12. enum SexEnum {
    13. MAN, WOMAN
    14. }
    15. @Data
    16. static class City {
    17. private String no;
    18. private String name;
    19. }
    20. }
    21. 复制代码

    这个时候@ConfigurationProperties(prefix = “jiuxian”) 注解会报错not registered via @EnableConfigurationProperties or marked as Spring component。这需要加上@EnableConfigurationProperties就可以了

    1. @EnableConfigurationProperties({ JiuxianProperties.class })
    2. @SpringBootApplication
    3. public class SpringbootYmlApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(SpringbootYmlApplication.class, args);
    6. }
    7. }
    8. 复制代码

    四、看效果

    然后输入 mvn clean package
    这个时候properties和yml文件已经可以提示了,不过有一些会有问题,比如jiuxian.school,这是一个对象,idea并不能解析,而因为City对象是个内部类是可以解析的。
    如图:
    Spring Boot 如何让yml,properties配置文件有提示 - 图1Spring Boot 如何让yml,properties配置文件有提示 - 图2
    如何处理呢? 只需要加上 @NestedConfigurationProperty注解即可

    1. @NestedConfigurationProperty
    2. private School school;
    3. 复制代码

    然后输入命令 mvn clean package
    警告消失(会有一点延迟)

    五、为什么

    为什么一定要打包编译后才可以呢?
    看一下打包过后的结构,如图:
    Spring Boot 如何让yml,properties配置文件有提示 - 图3
    idea之所以会代码提示就是因为这个spring-configuration-metadata.json json文件。这个文件的生成依据的就是我们上面的配置。

    六、进阶配置

    如果想在配置文件中能够提示该字段描述,以及该字段可选参数,是否弃用等信息时,需要加额外的配置

    1. 在resources目录下新建META-INF文件夹,加一个additional-spring-configuration-metadata.json 配置文件

    (1)该配置文件的节点信息

  • groups 有以下属性:

    • name group的全名,该属性必须
    • type group数据类型的类名。例如,如果group是基于一个被@ConfigurationProperties注解的类,该属性将包含该类的全限定名。如果基于一个@Bean方法,它将是该方法的返回类型。如果该类型未知,则该属性将被忽略
    • description 一个简短的group描述,用于展示给用户,要.点结尾。如果没有可用描述,该属性将被忽略
    • sourceType 来源类名。例如,如果组基于一个被@ConfigurationProperties注解的@Bean方法,该属性将包含@Configuration类的全限定名,该类包含此方法。如果来源类型未知,则该属性将被忽略
    • sourceMethod 该组的方法的全名(包含括号及参数类型)。例如,被@ConfigurationProperties注解的@Bean方法名。如果源方法未知,该属性将被忽略

“groups”是高级别的节点,它们本身不指定一个值,但为properties提供一个有上下文关联的分组。例如,server.port和server.servlet-path属性是server组的一部分。

注:不需要每个”property”都有一个”group”,一些属性可以以自己的形式存在。

  • properties
    • name 属性全名,格式为小写虚线分割的形式(jiuxian.name-en).必须要有的
    • type 属性数据类型,java.lang.Boolean。类型未知可忽略
    • description 该属性的描述
    • sourceType 来源类型,例如,如果property来自一个被@ConfigurationProperties注解的类,该属性将包括该类的全限定名。如果来源类型未知则该属性会被忽略
    • defaultValue 定义输入时的默认值,只是提示,并不是真正的默认值,可忽略
    • deprecated 是否废弃 boolean 值
      • level 级别 error,warning
      • reason 废弃原因
      • replacement 替代属性,为properties 全名
  • hints 可以给属性提供可选的值,以级描述
    • name 属性全名,不能为空
    • values 可选的值

详细看示例

  1. {
  2. "groups": [
  3. {
  4. "name": "jiuxian",
  5. "sourceType": "com.jiuxian.config.JiuxianProperties",
  6. "type": "com.jiuxian.config.JiuxianProperties"
  7. },
  8. {
  9. "name": "jiuxian.school",
  10. "sourceType": "com.jiuxian.config.School",
  11. "type": "com.jiuxian.config.School",
  12. "sourceMethod": "getSchool()"
  13. }
  14. ],
  15. "properties": [
  16. {
  17. "name": "jiuxian.name",
  18. "sourceType": "com.jiuxian.config.JiuxianProperties",
  19. "type": "java.lang.String",
  20. "deprecation": {
  21. "level": "error",
  22. "reason": "replacement nameCn.",
  23. "replacement": "jiuxian.name-cn"
  24. }
  25. },
  26. {
  27. "name": "jiuxian.name-cn",
  28. "sourceType": "com.jiuxian.config.JiuxianProperties",
  29. "type": "java.lang.String",
  30. "defaultValue": "jiuxian"
  31. }
  32. ],
  33. "hints": [
  34. {
  35. "name": "jiuxian.sex-enum",
  36. "values": [
  37. {
  38. "value": "man",
  39. "description": "man."
  40. },
  41. {
  42. "value": "woman",
  43. "description": "woman."
  44. }
  45. ]
  46. },
  47. {
  48. "name": "jiuxian.single",
  49. "values": [
  50. {
  51. "value": true,
  52. "description": "yes."
  53. },
  54. {
  55. "value": false,
  56. "description": "no."
  57. }
  58. ]
  59. }
  60. ]
  61. }
  62. 复制代码

idea 提示:
Spring Boot 如何让yml,properties配置文件有提示 - 图4
(2) 如何废弃某个字段,可以用代码来注解

  1. @Deprecated
  2. private String name;
  3. @Deprecated
  4. public String getName() {
  5. return getNameCn();
  6. }
  7. @DeprecatedConfigurationProperty(replacement = "jiuxian.name-cn", reason = "replacement nameCn")
  8. public void setName(String name) {
  9. setNameCn(name);
  10. }
  11. 复制代码

七、更多详细介绍请参阅官网

Spring官网介绍

八、本文示例代码

GitHub 源码

【注】以上代码基于Springboot 2.0