代码是写给人看的,不是写给机器看的,只是顺便计算机能够执行而已
——《计算机程序的结构和解释(SICP)》
导言
在咱们的我的项目里常常会呈现须要增加自定义配置的利用场景,例如某个开关变量,在测试环境关上,在生产环境不关上,通常咱们都会应用上面的代码来实现,而后在 Spring Boot 配置文件中增加这个 key 和 Value
Application.java:
application.properties
或者是没有应用 @Value 而间接在 XML 中应用咱们配置的属性值
application.xml
这样的代码和配置在 Spring Boot 我的项目中能够失常启动并读取配置,然而在咱们的 IDE 中却不会为咱们提醒配置的类型和代码补全。当咱们有新共事到来,或者是须要为配置文件增加新的环境的反对的时候,咱们很容易会把配置文件的 Key 拼错,或者 Value 的值与咱们的变量类型并不兼容(实际上真的产生过这样的问题导致我的项目启动失败)。
然而在咱们应用 Spring Boot 提供的配置的时候,IDE 总是能为咱们主动补全,通知咱们这个配置的变量类型,甚至是给咱们把这个配置的形容显示进去。
咱们是否也能够为咱们本人写的配置增加这样的 IDE 反对呢?
配置项元数据(Configuration Metadata)
Spring Boot 的 Jar 文件蕴含元数据文件,这些文件提供了咱们所须要的配置属性的详细信息。IDE 通过读取这些元数据文件,而后在应用 application.properties 或 application.yml 的时候提供上下文信息和代码补全。那么只有晓得如何编写并寄存配置项元数据信息文件,咱们也能够让 IDE 晓得如何为咱们的自定义配置提供上下文信息。
元数据格式
Spring Boot 我的项目的配置项元数据文件都放在 META-INF/spring-configuration-metadata.json 中。下图是当咱们配置好 Spring Boot 我的项目后默认应用的 Spring Boot 主动配置的配置项元数据寄存的地位
配置项元数据文件依照 groups, properties 和 hints 组织。properties 下的每个 property 都是程序中须要应用的配置项的 key 值,比方 server.port 是服务启动后的端口号。而咱们能够将一些 property 依照某些规定组合起来,这个组合就是 group(通常咱们并不需要为 properties 组织对应的 group)。而 hints 是为咱们的配置项提供额定的信息,比方时区 time.zone 反对 Asia/Shanghai,咱们能够为它提供 ”Asia/Shanghai” 的 hint。
properties 的参数
名称 | 类型 | 形容 |
---|---|---|
name | String | 属性的全名。名称是小写字母以句点宰割。此属性是必须的 |
type | String | 属性的数据类型的残缺签名(java.lang.String),如果是范型的话还该当蕴含残缺的范型参数(java.util.List<java.lang.String>)。为了保障一致性,须要应用包装类型来代替根本类型。此属性不是必须的,然而无奈失去类型诊断的反对。 |
hints 的参数
名称 | 类型 | 形容 |
---|---|---|
name | String | 该提醒所援用的属性的全称,和 properties 的 name 参数雷同。此属性是必须的 |
values | ValueHint[] | ValueHint 对象定义的有效值列表。每个条目都定义该值,并且能够具备形容 |
ValueHint 的参数
名称 | 类型 | 形容 |
---|---|---|
value | Object | property 给定的类型的有效值,如果 property 的类型是数组,那么它也能够是值的数组。此属性是必须的。如果是 Map 类型的属性,能够应用.keys 和.values 来指定对应的有效值。 |
description | String | 和 properties 的 description 雷同,提醒给用户的简短形容。此属性不是必须的。 |
这里只展现了咱们罕用的参数,对于配置项元数据文件格式的详细信息能够看 Spring Boot 的官网文档(https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-configuration-metadata.html#configuration-metadata-format)
为自定义配置编写配置项元数据
接下来咱们将对值、数组场景编写对应的配置项元数据,并为这些配置项增加提醒(Talk is cheap,show me the code)
在 IDE 中理论应用的成果
不过这种形式尽管好,然而须要咱们写很多的 JSON 配置来通知 IDE 该如何进行代码补全和附加上下文信息,配置和代码还是处于拆散的状态,如果能通过写一个配置类,间接通过这个类和它的正文 就能为咱们做到 IDE 反对就好了——Spring Boot 开发者也是这么想的。
为代码主动生成配置项元数据
首先咱们要改掉随处应用 @Value 的习惯,应用专门的数据类来寄存咱们的配置项
接下来咱们创立一个 Bean,让 Spring Boot 容器来接管这个类的实例
通过 @ConfigurationProperties 注解,Spring 就会主动将配置注入到咱们的配置 Bean 中,然而此时 IDE 还无奈辨认咱们增加的主动配置,咱们须要增加 Spring Boot 的注解处理器(annotation processor,从 Java 1.6 开始反对的个性)
增加注解处理器后从新编译,咱们就会在 target 目录下看到主动生成的 META-INF/spring-configuration-metadata.json
外面的内容根本就是咱们之前本人手动输出的内容,只是受于 Java 代码表白信息的局限性,没有方法生成 hints 信息。其中 sourceType 和 sourceMethod 属性还能够帮忙 IDE 跳转到咱们申明这个配置的类和办法
如果咱们想要让咱们应用代码生成的配置类也能增加提醒的话,能够在咱们的 META-INF 目录下增加 additional-spring-configuration-metadata.json 文件,将 hints 写到这个文件外面
这样 Spring Boot 在编译的时候就会将咱们的提示信息合并到配置信息元数据文件外面了
尽管这些工作不会减少代码的运行效率,然而让咱们的配置集中起来并有 IDE 的加成,会让咱们更改配置的时候更加有信念。正如结尾所说的,代码是写给人看的,不是写给机器看的,只是顺便计算机能够执行而已。