Springboot實現基於字首的自定義配置和自動提示功能

FeelTouch發表於2019-05-11

一、實現基於字首的自定義配置

1. 引入maven依賴

<!-- @ConfigurationProperties annotation processing (metadata for IDEs) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

注:該依賴非常強大,有興趣可下載原始碼檢視實現方式,基於工廠模式

2.配置類


@Configuration
@ConfigurationProperties(prefix = "rocketmq.consume") 
public class MqConsumeClientConfig {

    private String nameServer;

    private String groupName;

    private String instanceName;

    private String isTransaction;

    private Map<String, String> topics;

    private Map<String, String> tags;

}

@Configuration
@ConfigurationProperties(prefix = "rocketmq.produce")
public class MqProduceClientConfig {


    private String nameServer;

    private String groupName;

    private String instanceName;

    private String isTransaction;

    private Map<String, String> topics;

    private Map<String, String> tags;

    @Bean(name = "mqProducer")
    public DefaultRocketMqProducer defaultRocketMqProducer() {
            return new DefaultRocketMqProducer();
    }

    @Bean(name = "producer")
    public DefaultMQProducer defaultMQProducer( ) {
        DefaultMQProducer producer = new DefaultMQProducer(groupName);
        producer.setNamesrvAddr(nameServer);
        producer.setVipChannelEnabled(false);
        try {
            producer.start();
        } catch (MQClientException e) {
            System.exit(1);
            return null;
        }
        return producer;
    }

}
@Configuration 
@ConfigurationProperties(prefix = "rocketmq.produce")

配合使用,@Configuration 指明配置類;@ConfigurationProperties(prefix = "rocketmq.*") 指明字首

3. 配置檔案

rocketmq:
    produce:
       nameServer: 127.0.0.1:9876
       groupName: ProduceAccountGroupDev
       instanceName: ProduceAccountInstanceDev
       isTransaction: 0
       topics:
           key1: AccountTopicDev
           key2: AnswerTopicDev
       tags:
            key1: AccountTag1Dev
            key2: AccountTag1Dev
    consume:
       nameServer: 127.0.0.1:9876
       groupName: ConsumeAccountGroupDev
       instanceName: ConsumeAccountInstanceDev
       isTransaction: 0
       topics:
           key1: AccountTopicDev
           key2: AnswerTopicDev
       tags:
           key1: All
           key2: All

二、實現自動提示

一般在我們開發中,屬性檔案會產生一個自動提示,這個自定義提示也可以把我們的配置類新增到提示中。其實這是後設資料檔案氣的作用,

提供所有支援的配置屬性的詳細資訊。這些檔案旨在允許IDE開發人員在使用者使用application.properties 或application.yml檔案時提供上下文幫助和“程式碼完成” 。

主要的後設資料檔案是在編譯器通過處理所有被@ConfigurationProperties註解的節點來自動生成的。

1. 後設資料 spring-configuration-metadata.json

配置後設資料位於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”,一些屬性可以以自己的形式存在。

2. 配置後設資料步驟

1) 仍然是引入同樣的依賴

2) 在\resources\META-INF\下新增spring-configuration-metadata.json檔案。該檔案可以由idea生成。

3. 生成後設資料檔案

1)仍然是引入同樣的依賴

2)利用idea生成spring-configuration-metadata.json檔案

     在idea中, Ctrl + Alt + S 快捷鍵開啟Settings,搜尋Annotation Processors,接下來勾住Enable annonation processing儲存;重新編譯專案。

此時可以在編譯後的檔案中看到自動生成的spring-configuration-metadata.json。

進一步開啟檔案如下:

{
  "hints": [],
  "groups": [
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume",
      "type": "com.feeler.interlive.config.MqConsumeClientConfig"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce",
      "type": "com.feeler.interlive.config.MqProduceClientConfig"
    }
  ],
  "properties": [
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.group-name",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.instance-name",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.is-transaction",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.name-server",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.tags",
      "type": "java.util.Map<java.lang.String,java.lang.String>"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqConsumeClientConfig",
      "name": "rocketmq.consume.topics",
      "type": "java.util.Map<java.lang.String,java.lang.String>"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.group-name",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.instance-name",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.is-transaction",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.name-server",
      "type": "java.lang.String"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.tags",
      "type": "java.util.Map<java.lang.String,java.lang.String>"
    },
    {
      "sourceType": "com.feeler.interlive.config.MqProduceClientConfig",
      "name": "rocketmq.produce.topics",
      "type": "java.util.Map<java.lang.String,java.lang.String>"
    }
  ]
}

到此為止,已經實現了基於字首配置和自動提示功能

參考:https://blog.csdn.net/L_Sail/article/details/70342023

相關文章