您的位置:首页 > 编程语言 > Java开发

二十七、配置元数据

2017-04-22 00:21 393 查看

元数据

Spring Boot jar包含元数据文件,提供所有支持的配置属性的详细信息。这些文件旨在允许IDE开发人员在用户使用application.properties 或application.yml文件时提供上下文帮助和“代码完成” 。

主要的元数据文件是在编译器通过处理所有被@ConfigurationProperties注解的节点来自动生成的。

元数据格式

配置元数据位于jars文件中的META-INF/spring-configuration-metadata.json,它们使用一个具有”groups”或”properties”分类节点的简单JSON格式:

{"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
}
...
],"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.servlet-path",
"type": "java.lang.String",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
"defaultValue": "/"
}
...
]}


每个”property”是一个配置节点,用户可以使用特定的值指定它。例如,server.port和server.servlet-path可能在application.properties中如以下定义:

server.port=9090
server.servlet-path=/home


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

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

Group属性

groups数组包含的JSON对象可以由以下属性组成:

名称类型目的
nameStringgroup的全名,该属性是强制性的
typeStringgroup数据类型的类名。例如,如果group是基于一个被@ConfigurationProperties注解的类,该属性将包含该类的全限定名。如果基于一个@Bean方法,它将是该方法的返回类型。如果该类型未知,则该属性将被忽略
descriptionString一个简短的group描述,用于展示给用户。如果没有可用描述,该属性将被忽略。推荐使用一个简短的段落描述,第一行提供一个简洁的总结,最后一行以句号结尾
sourceTypeString贡献该组的来源类名。例如,如果组基于一个被@ConfigurationProperties注解的@Bean方法,该属性将包含@Configuration类的全限定名,该类包含此方法。如果来源类型未知,则该属性将被忽略
sourceMethodString贡献该组的方法的全名(包含括号及参数类型)。例如,被@ConfigurationProperties注解的@Bean方法名。如果源方法未知,该属性将被忽略

Property属性

properties数组中包含的JSON对象可由以下属性构成:

名称类型目的
nameStringproperty的全名,格式为小写虚线分割的形式(比如server.servlet-path)。该属性是强制性的
typeStringproperty数据类型的类名。例如java.lang.String。该属性可以用来指导用户他们可以输入值的类型。为了保持一致,原生类型使用它们的包装类代替,比如boolean变成了java.lang.Boolean。注意,这个类可能是个从一个字符串转换而来的复杂类型。如果类型未知则该属性会被忽略
descriptionString一个简短的组的描述,用于展示给用户。如果没有描述可用则该属性会被忽略。推荐使用一个简短的段落描述,开头提供一个简洁的总结,最后一行以句号结束
sourceTypeString贡献property的来源类名。例如,如果property来自一个被@ConfigurationProperties注解的类,该属性将包括该类的全限定名。如果来源类型未知则该属性会被忽略
defaultValueObject当property没有定义时使用的默认值。如果property类型是个数组则该属性也可以是个数组。如果默认值未知则该属性会被忽略
deprecatedboolean指定该property是否过期。如果该字段没有过期或该信息未知则该属性会被忽略
deprecation每个properties元素的属性中包含的JSON对象可以包含以下属性:

名称类型目的
reasonstring简短描述了该资源被弃用的原因。如果没有理由可以省略。建议描述是一个简短的段落,第一行提供简明扼要的摘要。说明中的最后一行应以period(.)结尾。
replacementstring正在替换此不推荐使用的属性的属性的全名。如果没有替换此属性,可以省略。
在Spring Boot 1.3之前,deprecated可以使用单个布尔属性来代替deprecation元素。这仍然以不推荐的方式支持,不应再使用。如果没有理由和替换可用,deprecation应该设置一个空的对象。

hints

hints数组中包含的JSON对象可以包含以下属性:

名称类型目的
name该提示引用的属性的全名。名称以小写虚构形式(例如server.servlet-path)。果属性是指地图(例如 system.contexts),则提示可以应用于map()或values()的键。此属性是强制性的system.context.keyssystem.context.values
valuesValueHint由ValueHint对象定义的有效值的列表(见下文)。每个条目定义该值并且可以具有描述
providersValueProvider []由ValueProvider对象定义的提供者列表(见下文)。每个条目定义提供者的名称及其参数(如果有)。


可重复的元数据节点

在同一个元数据文件中出现多次相同名称的”property”和”group”对象是可以接受的。例如,Spring Boot将spring.datasource属性绑定到Hikari,Tomcat和DBCP类,并且每个都潜在的提供了重复的属性名。这些元数据的消费者需要确保他们支持这样的场景。

提供手动提示

为了改善用户体验并进一步协助用户配置给定的属性,您可以提供额外的元数据:

描述属性的潜在值列表。

关联一个提供者以将一个明确定义的语义附加到一个属性,这样工具就可以根据项目的上下文来发现潜在值的列表。

创建Javaconfig文件

package com.lf.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
* Created by LF on 2017/4/18.
*/
@ConfigurationProperties(prefix = "spring.druid")
public class DruidSource {

private String dbUrl;

private String username;

private String password;

private String driverClassName;

private int initialSize;

private int minIdle;

private int maxActive;

private int maxWait;

private int timeBetweenEvictionRunsMillis;

private int minEvictableIdleTimeMillis;
private String validationQuery;

private boolean testWhileIdle;
private boolean testOnBorrow;

private boolean testOnReturn;

private boolean poolPreparedStatements;

private int maxPoolPreparedStatementPerConnectionSize;

private String filters;

private String connectionProperties;

public String getDbUrl() {
return dbUrl;
}

public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getDriverClassName() {
return driverClassName;
}

public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}

public int getInitialSize() {
return initialSize;
}

public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}

public int getMinIdle() {
return minIdle;
}

public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}

public int getMaxActive() {
return maxActive;
}

public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}

public int getMaxWait() {
return maxWait;
}

public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}

public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}

public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}

public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}

public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}

public String getValidationQuery() {
return validationQuery;
}

public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}

public boolean isTestWhileIdle() {
return testWhileIdle;
}

public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}

public boolean isTestOnBorrow() {
return testOnBorrow;
}

public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}

public boolean isTestOnReturn() {
return testOnReturn;
}

public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}

public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}

public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}

public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}

public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}

public String getFilters() {
return filters;
}

public void setFilters(String filters) {
this.filters = filters;
}

public String getConnectionProperties() {
return connectionProperties;
}

public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
}


添加maven依赖

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


添加spring-configuration-metadata.json

在\resources\META-INF\下添加spring-configuration-metadata.json文件

内容如下:

{
"hints": [],
"groups": [
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid",
"type": "com.lf.datasource.DruidSource"
}
],
"properties": [
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.connection-properties",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.db-url",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.driver-class-name",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.filters",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.initial-size",
"type": "java.lang.Integer"
},
{
"name": "spring.druid.initialSize",
"description": "Description for spring.datasource.initialSize.",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.max-active",
"type": "java.lang.Integer"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.max-pool-prepared-statement-per-connection-size",
"type": "java.lang.Integer"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.max-wait",
"type": "java.lang.Integer"
},
{
"name": "spring.druid.maxActive",
"description": "Description for spring.datasource.maxActive.",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.min-evictable-idle-time-millis",
"type": "java.lang.Integer"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.min-idle",
"type": "java.lang.Integer"
},
{
"name": "spring.druid.minIdle",
"description": "Description for spring.datasource.minIdle.",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.password",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": false,
"name": "spring.druid.pool-prepared-statements",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": false,
"name": "spring.druid.test-on-borrow",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": false,
"name": "spring.druid.test-on-return",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": false,
"name": "spring.druid.test-while-idle",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"defaultValue": 0,
"name": "spring.druid.time-between-eviction-runs-millis",
"type": "java.lang.Integer"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.username",
"type": "java.lang.String"
},
{
"sourceType": "com.lf.datasource.DruidSource",
"name": "spring.druid.validation-query",
"type": "java.lang.String"
}
]
}


编译项目(一定要编译项目)

创建application文件配置

如下的属性就可以自动提示,有点ide工具可能不支持,idea可以完美支持

```
#连接池的配置信息
## 初始化大小,最小,最大
spring.druid.initialSize=5
spring.druid.minIdle=5
spring.druid.maxActive=20
## 配置获取连接等待超时的时间
spring.druid.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.druid.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.druid.minEvictableIdleTimeMillis=300000
spring.druid.validationQuery=SELECT 1 FROM DUAL
spring.druid.testWhileIdle=true
spring.druid.testOnBorrow=false
spring.druid.testOnReturn=false
spring.druid.poolPreparedStatements=true
spring.druid.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.druid.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息