Rename @ConfigurationPropertiesImport

Rename `@ConfigurationPropertiesImport` to
`@ImportAsConfigurationPropertiesBean` and also refine the registrar
so that it can be used with type directly annotated with
`@ConfigurationProperties`.

Closes gh-23172
This commit is contained in:
Phillip Webb
2020-09-15 10:51:30 -07:00
parent 7d5f33170e
commit 5f49d4a8d7
25 changed files with 260 additions and 130 deletions

View File

@@ -80,9 +80,9 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
static final String NAME_ANNOTATION = "org.springframework.boot.context.properties.bind.Name";
static final String CONFIGURATION_PROPERTIES_IMPORT_ANNOATION = "org.springframework.boot.context.properties.ConfigurationPropertiesImport";
static final String IMPORT_AS_CONFIGURATION_PROPERTIES_BEAN_ANNOATION = "org.springframework.boot.context.properties.ImportAsConfigurationPropertiesBean";
static final String CONFIGURATION_PROPERTIES_IMPORTS_ANNOATION = "org.springframework.boot.context.properties.ConfigurationPropertiesImports";
static final String IMPORT_AS_CONFIGURATION_PROPERTIES_BEANS_ANNOATION = "org.springframework.boot.context.properties.ImportAsConfigurationPropertiesBeans";
private static final Set<String> SUPPORTED_OPTIONS = Collections
.unmodifiableSet(Collections.singleton(ADDITIONAL_METADATA_LOCATIONS_OPTION));
@@ -125,12 +125,12 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
return NAME_ANNOTATION;
}
protected String configurationPropertiesImportAnnotation() {
return CONFIGURATION_PROPERTIES_IMPORT_ANNOATION;
protected String importAsConfigurationPropertiesBeanAnnotation() {
return IMPORT_AS_CONFIGURATION_PROPERTIES_BEAN_ANNOATION;
}
protected String configurationPropertiesImportsAnnotation() {
return CONFIGURATION_PROPERTIES_IMPORTS_ANNOATION;
protected String importAsConfigurationPropertiesBeansAnnotation() {
return IMPORT_AS_CONFIGURATION_PROPERTIES_BEANS_ANNOATION;
}
@Override
@@ -151,8 +151,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
this.metadataEnv = new MetadataGenerationEnvironment(env, configurationPropertiesAnnotation(),
nestedConfigurationPropertyAnnotation(), deprecatedConfigurationPropertyAnnotation(),
constructorBindingAnnotation(), defaultValueAnnotation(), endpointAnnotation(),
readOperationAnnotation(), nameAnnotation(), configurationPropertiesImportAnnotation(),
configurationPropertiesImportsAnnotation());
readOperationAnnotation(), nameAnnotation(), importAsConfigurationPropertiesBeanAnnotation(),
importAsConfigurationPropertiesBeansAnnotation());
}
@Override
@@ -160,7 +160,7 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
this.metadataCollector.processing(roundEnv);
processConfigurationProperties(roundEnv);
processEndpoint(roundEnv);
processConfigurationPropertiesImport(roundEnv);
processImportAsConfigurationProperties(roundEnv);
if (roundEnv.processingOver()) {
try {
writeMetaData();
@@ -188,22 +188,22 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
}
}
private void processConfigurationPropertiesImport(RoundEnvironment roundEnv) {
TypeElement configurationPropertiesImportType = this.metadataEnv
.getConfigurationPropertiesImportAnnotationElement();
TypeElement configurationPropertiesImportsType = this.metadataEnv
.getConfigurationPropertiesImportsAnnotationElement();
if (configurationPropertiesImportType == null && configurationPropertiesImportsType == null) {
private void processImportAsConfigurationProperties(RoundEnvironment roundEnv) {
TypeElement importAsConfigurationPropertiesBeanType = this.metadataEnv
.getImportAsConfigurationPropertiesBeansAnnotation();
TypeElement importAsConfigurationPropertiesBeansType = this.metadataEnv
.getImportAsConfigurationPropertiesBeansAnnotationElement();
if (importAsConfigurationPropertiesBeanType == null && importAsConfigurationPropertiesBeansType == null) {
return;
}
Set<Element> elements = new LinkedHashSet<>();
if (configurationPropertiesImportType != null) {
elements.addAll(roundEnv.getElementsAnnotatedWith(configurationPropertiesImportType));
if (importAsConfigurationPropertiesBeanType != null) {
elements.addAll(roundEnv.getElementsAnnotatedWith(importAsConfigurationPropertiesBeanType));
}
if (configurationPropertiesImportsType != null) {
elements.addAll(roundEnv.getElementsAnnotatedWith(configurationPropertiesImportsType));
if (importAsConfigurationPropertiesBeansType != null) {
elements.addAll(roundEnv.getElementsAnnotatedWith(importAsConfigurationPropertiesBeansType));
}
elements.forEach(this::processConfigurationPropertiesImport);
elements.forEach(this::processImportAsConfigurationPropertiesBean);
}
private Map<Element, List<Element>> getElementsAnnotatedOrMetaAnnotatedWith(RoundEnvironment roundEnv,
@@ -314,18 +314,28 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
}
}
private void processConfigurationPropertiesImport(Element element) {
this.metadataEnv.getConfigurationPropertiesImportAnnotations(element)
.forEach(this::processConfigurationPropertiesImport);
private void processImportAsConfigurationPropertiesBean(Element element) {
this.metadataEnv.getImportAsConfigurationPropertiesBeanAnnotations(element)
.forEach(this::processImportAsConfigurationPropertiesBean);
}
@SuppressWarnings("unchecked")
private void processConfigurationPropertiesImport(AnnotationMirror annotation) {
private void processImportAsConfigurationPropertiesBean(AnnotationMirror annotation) {
String prefix = getPrefix(annotation);
List<TypeMirror> types = (List<TypeMirror>) this.metadataEnv.getAnnotationElementValues(annotation).get("type");
for (TypeMirror type : types) {
Element element = this.metadataEnv.getTypeUtils().asElement(type);
processAnnotatedTypeElement(prefix, (TypeElement) element, true, new Stack<>());
processImportAsConfigurationPropertiesBeanTypes(prefix,
(List<TypeMirror>) this.metadataEnv.getAnnotationElementValues(annotation).get("type"));
processImportAsConfigurationPropertiesBeanTypes(prefix,
(List<TypeMirror>) this.metadataEnv.getAnnotationElementValues(annotation).get("value"));
}
private void processImportAsConfigurationPropertiesBeanTypes(String prefix, List<TypeMirror> types) {
if (types != null) {
for (TypeMirror type : types) {
Element element = this.metadataEnv.getTypeUtils().asElement(type);
AnnotationMirror annotation = this.metadataEnv.getConfigurationPropertiesAnnotation(element);
prefix = (annotation != null) ? getPrefix(annotation) : prefix;
processAnnotatedTypeElement(prefix, (TypeElement) element, true, new Stack<>());
}
}
}

View File

@@ -97,15 +97,15 @@ class MetadataGenerationEnvironment {
private final String nameAnnotation;
private final String configurationPropertiesImportAnnotation;
private final String importAsConfigurationPropertiesBeanAnnotation;
private final String configurationPropertiesImportsAnnotation;
private final String importAsConfigurationPropertiesBeansAnnotation;
MetadataGenerationEnvironment(ProcessingEnvironment environment, String configurationPropertiesAnnotation,
String nestedConfigurationPropertyAnnotation, String deprecatedConfigurationPropertyAnnotation,
String constructorBindingAnnotation, String defaultValueAnnotation, String endpointAnnotation,
String readOperationAnnotation, String nameAnnotation, String configurationPropertiesImportAnnotation,
String configurationPropertiesImportsAnnotation) {
String readOperationAnnotation, String nameAnnotation, String importAsConfigurationPropertiesBeanAnnotation,
String importAsConfigurationPropertiesBeansAnnotation) {
this.typeUtils = new TypeUtils(environment);
this.elements = environment.getElementUtils();
this.messager = environment.getMessager();
@@ -118,8 +118,8 @@ class MetadataGenerationEnvironment {
this.endpointAnnotation = endpointAnnotation;
this.readOperationAnnotation = readOperationAnnotation;
this.nameAnnotation = nameAnnotation;
this.configurationPropertiesImportAnnotation = configurationPropertiesImportAnnotation;
this.configurationPropertiesImportsAnnotation = configurationPropertiesImportsAnnotation;
this.importAsConfigurationPropertiesBeanAnnotation = importAsConfigurationPropertiesBeanAnnotation;
this.importAsConfigurationPropertiesBeansAnnotation = importAsConfigurationPropertiesBeansAnnotation;
}
private static FieldValuesParser resolveFieldValuesParser(ProcessingEnvironment env) {
@@ -265,12 +265,12 @@ class MetadataGenerationEnvironment {
return this.elements.getTypeElement(this.configurationPropertiesAnnotation);
}
TypeElement getConfigurationPropertiesImportAnnotationElement() {
return this.elements.getTypeElement(this.configurationPropertiesImportAnnotation);
TypeElement getImportAsConfigurationPropertiesBeansAnnotation() {
return this.elements.getTypeElement(this.importAsConfigurationPropertiesBeanAnnotation);
}
TypeElement getConfigurationPropertiesImportsAnnotationElement() {
return this.elements.getTypeElement(this.configurationPropertiesImportsAnnotation);
TypeElement getImportAsConfigurationPropertiesBeansAnnotationElement() {
return this.elements.getTypeElement(this.importAsConfigurationPropertiesBeansAnnotation);
}
AnnotationMirror getConfigurationPropertiesAnnotation(Element element) {
@@ -297,13 +297,13 @@ class MetadataGenerationEnvironment {
return getAnnotation(element, this.nameAnnotation);
}
List<AnnotationMirror> getConfigurationPropertiesImportAnnotations(Element element) {
List<AnnotationMirror> getImportAsConfigurationPropertiesBeanAnnotations(Element element) {
List<AnnotationMirror> annotations = new ArrayList<>();
AnnotationMirror importBean = getAnnotation(element, this.configurationPropertiesImportAnnotation);
AnnotationMirror importBean = getAnnotation(element, this.importAsConfigurationPropertiesBeanAnnotation);
if (importBean != null) {
annotations.add(importBean);
}
AnnotationMirror importBeans = getAnnotation(element, this.configurationPropertiesImportsAnnotation);
AnnotationMirror importBeans = getAnnotation(element, this.importAsConfigurationPropertiesBeansAnnotation);
if (importBeans != null) {
AnnotationValue value = importBeans.getElementValues().values().iterator().next();
for (Object contained : (List<?>) value.getValue()) {

View File

@@ -50,7 +50,7 @@ class PropertyDescriptorResolver {
* factory method}, if any.
* @param type the target type
* @param fromImport it the type was imported via a
* {@code @ConfigurationPropertiesImport}
* {@code @ImportAsConfigurationPropertiesBean}
* @param factoryMethod the method that triggered the metadata for that {@code type}
* or {@code null}
* @return the candidate properties for metadata generation

View File

@@ -20,20 +20,22 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
import org.springframework.boot.configurationprocessor.metadata.Metadata;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImport;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImports;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBeans;
import org.springframework.boot.configurationsample.importbean.ImportAnnotatedJavaBean;
import org.springframework.boot.configurationsample.importbean.ImportJavaBeanConfigurationPropertiesBean;
import org.springframework.boot.configurationsample.importbean.ImportMultipleTypeConfigurationPropertiesBean;
import org.springframework.boot.configurationsample.importbean.ImportRepeatedConfigurationPropertiesBean;
import org.springframework.boot.configurationsample.importbean.ImportValueObjectConfigurationPropertiesBean;
import org.springframework.boot.configurationsample.importbean.ImportedAnnotatedJavaBean;
import org.springframework.boot.configurationsample.importbean.ImportedJavaBean;
import org.springframework.boot.configurationsample.importbean.ImportedValueObject;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ConfigurationPropertiesImport} and
* {@link ConfigurationPropertiesImports}.
* Tests for {@link ImportAsConfigurationPropertiesBean} and
* {@link ImportAsConfigurationPropertiesBeans}.
*
* @author Phillip Webb
*/
@@ -69,4 +71,11 @@ public class ImportBeanTests extends AbstractMetadataGenerationTests {
assertThat(metadata).has(Metadata.withProperty("jb.name", String.class).fromSource(ImportedJavaBean.class));
}
@Test
void importAnnotatedJavaBean() {
ConfigurationMetadata metadata = compile(ImportAnnotatedJavaBean.class);
assertThat(metadata)
.has(Metadata.withProperty("test.name", String.class).fromSource(ImportedAnnotatedJavaBean.class));
}
}

View File

@@ -40,8 +40,8 @@ class MetadataGenerationEnvironmentFactory implements Function<ProcessingEnviron
TestConfigurationMetadataAnnotationProcessor.ENDPOINT_ANNOTATION,
TestConfigurationMetadataAnnotationProcessor.READ_OPERATION_ANNOTATION,
TestConfigurationMetadataAnnotationProcessor.NAME_ANNOTATION,
TestConfigurationMetadataAnnotationProcessor.CONFIGURATION_PROPERTIES_IMPORT_ANNOATION,
TestConfigurationMetadataAnnotationProcessor.CONFIGURATION_PROPERTIES_IMPORTS_ANNOATION);
TestConfigurationMetadataAnnotationProcessor.IMPORT_AS_CONFIGURATION_PROPERTIES_BEAN_ANNOATION,
TestConfigurationMetadataAnnotationProcessor.IMPORT_AS_CONFIGURATION_PROPERTIES_BEANS_ANNOATION);
}
}

View File

@@ -57,9 +57,9 @@ public class TestConfigurationMetadataAnnotationProcessor extends ConfigurationM
public static final String NAME_ANNOTATION = "org.springframework.boot.configurationsample.Name";
public static final String CONFIGURATION_PROPERTIES_IMPORT_ANNOATION = "org.springframework.boot.configurationsample.ConfigurationPropertiesImport";
public static final String IMPORT_AS_CONFIGURATION_PROPERTIES_BEAN_ANNOATION = "org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean";
public static final String CONFIGURATION_PROPERTIES_IMPORTS_ANNOATION = "org.springframework.boot.configurationsample.ConfigurationPropertiesImports";
public static final String IMPORT_AS_CONFIGURATION_PROPERTIES_BEANS_ANNOATION = "org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBeans";
private ConfigurationMetadata metadata;
@@ -110,13 +110,13 @@ public class TestConfigurationMetadataAnnotationProcessor extends ConfigurationM
}
@Override
protected String configurationPropertiesImportAnnotation() {
return CONFIGURATION_PROPERTIES_IMPORT_ANNOATION;
protected String importAsConfigurationPropertiesBeanAnnotation() {
return IMPORT_AS_CONFIGURATION_PROPERTIES_BEAN_ANNOATION;
}
@Override
protected String configurationPropertiesImportsAnnotation() {
return CONFIGURATION_PROPERTIES_IMPORTS_ANNOATION;
protected String importAsConfigurationPropertiesBeansAnnotation() {
return IMPORT_AS_CONFIGURATION_PROPERTIES_BEANS_ANNOATION;
}
@Override

View File

@@ -26,8 +26,8 @@ import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Alternative to Spring Boot's {@code ConfigurationPropertiesImport} for testing (removes
* the need for a dependency on the real annotation).
* Alternative to Spring Boot's {@code ImportAsConfigurationPropertiesBean} for testing
* (removes the need for a dependency on the real annotation).
*
* @author Phillip Webb
*/
@@ -35,8 +35,8 @@ import org.springframework.core.annotation.AliasFor;
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConfigurationProperties
@Repeatable(ConfigurationPropertiesImports.class)
public @interface ConfigurationPropertiesImport {
@Repeatable(ImportAsConfigurationPropertiesBeans.class)
public @interface ImportAsConfigurationPropertiesBean {
Class<?>[] type();

View File

@@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Alternative to Spring Boot's {@code ConfigurationPropertiesImports} for testing
* Alternative to Spring Boot's {@code ImportAsConfigurationPropertiesBeans} for testing
* (removes the need for a dependency on the real annotation).
*
* @author Phillip Webb
@@ -31,8 +31,8 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationPropertiesImports {
public @interface ImportAsConfigurationPropertiesBeans {
ConfigurationPropertiesImport[] value();
ImportAsConfigurationPropertiesBean[] value();
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
/**
* An import of a java bean.
*
* @author Phillip Webb
*/
@ImportAsConfigurationPropertiesBean(type = ImportedAnnotatedJavaBean.class)
public class ImportAnnotatedJavaBean {
}

View File

@@ -16,14 +16,14 @@
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImport;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
/**
* An import of a java bean.
*
* @author Phillip Webb
*/
@ConfigurationPropertiesImport(type = ImportedJavaBean.class, prefix = "importbean")
@ImportAsConfigurationPropertiesBean(type = ImportedJavaBean.class, prefix = "importbean")
public class ImportJavaBeanConfigurationPropertiesBean {
}

View File

@@ -16,14 +16,15 @@
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImport;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
/**
* An import of a java bean and a value object.
*
* @author Phillip Webb
*/
@ConfigurationPropertiesImport(type = { ImportedJavaBean.class, ImportedValueObject.class }, prefix = "importbean")
@ImportAsConfigurationPropertiesBean(type = { ImportedJavaBean.class, ImportedValueObject.class },
prefix = "importbean")
public class ImportMultipleTypeConfigurationPropertiesBean {
}

View File

@@ -16,15 +16,15 @@
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImport;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
/**
* An import of a java bean and a value object.
*
* @author Phillip Webb
*/
@ConfigurationPropertiesImport(type = ImportedJavaBean.class, prefix = "jb")
@ConfigurationPropertiesImport(type = ImportedValueObject.class, prefix = "vo")
@ImportAsConfigurationPropertiesBean(type = ImportedJavaBean.class, prefix = "jb")
@ImportAsConfigurationPropertiesBean(type = ImportedValueObject.class, prefix = "vo")
public class ImportRepeatedConfigurationPropertiesBean {
}

View File

@@ -16,14 +16,14 @@
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ConfigurationPropertiesImport;
import org.springframework.boot.configurationsample.ImportAsConfigurationPropertiesBean;
/**
* An import of a value object.
*
* @author Phillip Webb
*/
@ConfigurationPropertiesImport(type = ImportedValueObject.class, prefix = "importbean")
@ImportAsConfigurationPropertiesBean(type = ImportedValueObject.class, prefix = "importbean")
public class ImportValueObjectConfigurationPropertiesBean {
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.configurationsample.importbean;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Java bean that can be imported.
*
* @author Phillip Webb
*/
@ConfigurationProperties(prefix = "test")
public class ImportedAnnotatedJavaBean {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}