【问题标题】:Can I generate the spring boot configuration metadata as a .properties file我可以将 Spring Boot 配置元数据生成为 .properties 文件吗
【发布时间】:2020-02-12 14:03:06
【问题描述】:

如果我包含 spring-boot-configuration-processor 作为依赖项,我的构建将生成一个这样的 json 文件:

{
  "groups": [
    {
      "name": "attachments",
      "type": "com.example.config.AttachmentsSettings",
      "sourceType": "com.example.config.AttachmentsSettings"
    }
  ],
  "properties": [
    {
      "name": "attachments.max-size",
      "type": "java.lang.Integer",
      "sourceType": "com.example.config.AttachmentsSettings",
      "defaultValue": 1024
    },
    {
      "name": "attachments.min-size",
      "type": "java.lang.Integer",
      "sourceType": "com.example.config.AttachmentsSettings"
    },
    {
      "name": "attachments.invalid-chars",
      "type": "java.lang.String",
      "sourceType": "com.example.config.AttachmentsSettings",
      "defaultValue": "abc"
    }
  ],
  "hints": []
}

我想另外生成一个属性文件,列出所有属性及其默认值,如下所示:

attachments.max-size=1024
attachments.invalid-chars=abc
# attachments.min-size=

理想情况下,我还希望它列出没有默认值但被注释掉的属性。

是否可以使用 Spring Boot 做这样的事情?还是我需要自己写点东西?

【问题讨论】:

    标签: spring-boot spring-annotations annotation-processing spring-boot-configuration


    【解决方案1】:

    我可以像这样扩展 ConfigurationMetadataAnnotationProcessor:

    @SupportedAnnotationTypes({ "*" })
    public class MyConfigurationMetadataAnnotationProcessor extends ConfigurationMetadataAnnotationProcessor {
    
        @Override
        public synchronized void init(ProcessingEnvironment env) {
            super.init(env);
    
            Field metadataStoreField = ReflectionUtils.findField(ConfigurationMetadataAnnotationProcessor.class, "metadataStore");
            ReflectionUtils.makeAccessible(metadataStoreField);
            ReflectionUtils.setField(metadataStoreField, this, new MyMetadataStore(env));
        }
    
        private class MyMetadataStore extends MetadataStore {
    
            static final String METADATA_PROPERTIES_PATH = "META-INF/spring-configuration-metadata.properties";
            private final ProcessingEnvironment environment;
    
            public MyMetadataStore(ProcessingEnvironment environment) {
                super(environment);
                this.environment = environment;
            }
    
            @Override
            public void writeMetadata(ConfigurationMetadata metadata) throws IOException {
                if (!metadata.getItems().isEmpty()) {
                    try (OutputStream outputStream = createMetadataPropertiesResource().openOutputStream()) {
                        outputStream.write(getProps(metadata).getBytes(StandardCharsets.UTF_8));
                    }
                }
            }
    
            private String getProps(ConfigurationMetadata metadata) {
                return metadata.getItems().stream()
                        .filter(item -> item.isOfItemType(ItemMetadata.ItemType.PROPERTY))
                        .map(item -> nonNull(item.getDefaultValue()) ?
                                item.getName() + "=" + item.getDefaultValue() :
                                "# " + item.getName() + "=")
                        .collect(Collectors.joining("\n"));
            }
    
            private FileObject createMetadataPropertiesResource() throws IOException {
                return this.environment.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", METADATA_PROPERTIES_PATH);
            }
        }
    }
    

    然后将其作为服务添加到 META-INF 目录中:

    处理器文件只有一行: com.my.package.MyConfigurationMetadataAnnotationProcessor

    我需要分两个阶段编译它——首先编译处理器类,然后使用它来处理注释——如SO answer 中所述。

    【讨论】:

      猜你喜欢
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 2012-02-11
      • 1970-01-01
      • 2017-04-12
      • 2018-06-20
      • 2021-05-30
      相关资源
      最近更新 更多