Могу ли я сгенерировать метаданные конфигурации весенней загрузки в виде файла .properties - PullRequest
0 голосов
/ 12 февраля 2020

Если я включу 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? Или мне нужно что-то написать самому?

1 Ответ

0 голосов
/ 17 февраля 2020

Я могу расширить 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:

directory structure

где файл Processor имеет одну строку: com.my.package.MyConfigurationMetadataAnnotationProcessor

Мне нужно скомпилировать его в 2 этапа - сначала скомпилировать класс процессора, а затем использовать его для обработки аннотаций - как описано в этом ТАК ответ .

...