From 06b81cf16f91da74ef734a1b0989886e1ed9dca7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 20 Jun 2016 14:20:16 +0200 Subject: [PATCH] Use `@AliasFor` when applicable This commit adds `@AliasFor` meta-data to annotations that declare an alias attribute. `@ConditionalOnProperty` and `@AutoconfigureRestDocs` were not migrated due to the use of `AnnotationMetadata#getAnnotationAttributes`. Closes gh-5187 --- .../ConfigurationPropertiesReportEndpoint.java | 3 +-- .../boot/actuate/endpoint/mvc/MvcEndpoints.java | 5 +---- .../context/properties/ConfigurationProperties.java | 4 ++++ .../ConfigurationPropertiesBindingPostProcessor.java | 9 +++------ .../EnableConfigurationPropertiesImportSelector.java | 3 +-- .../context/scan/AbstractEntityScanRegistrar.java | 10 ---------- .../springframework/boot/neo4j/NodeEntityScan.java | 3 +++ .../org/springframework/boot/orm/jpa/EntityScan.java | 5 ++++- .../boot/web/servlet/ServletComponentScan.java | 5 ++++- .../web/servlet/ServletComponentScanRegistrar.java | 12 ++---------- .../boot/context/scan/TestEntityScan.java | 3 +++ .../boot/context/scan/TestEntityScanTests.java | 10 ++++++---- .../servlet/ServletComponentScanRegistrarTests.java | 12 ++++-------- 13 files changed, 36 insertions(+), 48 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java index 5160d4a00dc..2c495935930 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/ConfigurationPropertiesReportEndpoint.java @@ -220,8 +220,7 @@ public class ConfigurationPropertiesReportEndpoint annotation = override; } } - return (StringUtils.hasLength(annotation.value()) ? annotation.value() - : annotation.prefix()); + return annotation.prefix(); } /** diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoints.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoints.java index 05acf910586..8a860d26f2b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoints.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpoints.java @@ -30,7 +30,6 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; /** * A registry for all {@link MvcEndpoint} beans, and a factory for a set of generic ones @@ -102,9 +101,7 @@ public class MvcEndpoints implements ApplicationContextAware, InitializingBean { ConfigurationProperties configurationProperties = AnnotationUtils .findAnnotation(endpoint.getClass(), ConfigurationProperties.class); if (configurationProperties != null) { - String prefix = StringUtils.hasText(configurationProperties.prefix()) - ? configurationProperties.prefix() : configurationProperties.value(); - return environment.getProperty(prefix + ".path"); + return environment.getProperty(configurationProperties.prefix() + ".path"); } return null; } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationProperties.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationProperties.java index 5471a1ebd47..5010d60a563 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationProperties.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationProperties.java @@ -22,6 +22,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.core.annotation.AliasFor; + /** * Annotation for externalized configuration. Add this to a class definition or a * {@code @Bean} method in a {@code @Configuration} class if you want to bind and validate @@ -44,6 +46,7 @@ public @interface ConfigurationProperties { * for {@link #prefix()}. * @return the name prefix of the properties to bind */ + @AliasFor("prefix") String value() default ""; /** @@ -51,6 +54,7 @@ public @interface ConfigurationProperties { * for {@link #value()}. * @return the name prefix of the properties to bind */ + @AliasFor("value") String prefix() default ""; /** diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java index e6b7b4047ab..77700e213ca 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBindingPostProcessor.java @@ -325,10 +325,8 @@ public class ConfigurationPropertiesBindingPostProcessor factory.setIgnoreUnknownFields(annotation.ignoreUnknownFields()); factory.setExceptionIfInvalid(annotation.exceptionIfInvalid()); factory.setIgnoreNestedProperties(annotation.ignoreNestedProperties()); - String targetName = (StringUtils.hasLength(annotation.value()) - ? annotation.value() : annotation.prefix()); - if (StringUtils.hasLength(targetName)) { - factory.setTargetName(targetName); + if (StringUtils.hasLength(annotation.prefix())) { + factory.setTargetName(annotation.prefix()); } } try { @@ -346,8 +344,7 @@ public class ConfigurationPropertiesBindingPostProcessor return ""; } StringBuilder details = new StringBuilder(); - details.append("prefix=").append((StringUtils.hasLength(annotation.value()) - ? annotation.value() : annotation.prefix())); + details.append("prefix=").append(annotation.prefix()); details.append(", ignoreInvalidFields=").append(annotation.ignoreInvalidFields()); details.append(", ignoreUnknownFields=").append(annotation.ignoreUnknownFields()); details.append(", ignoreNestedProperties=") diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/EnableConfigurationPropertiesImportSelector.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/EnableConfigurationPropertiesImportSelector.java index 47ff826080a..35a25b209ff 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/EnableConfigurationPropertiesImportSelector.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/EnableConfigurationPropertiesImportSelector.java @@ -88,8 +88,7 @@ class EnableConfigurationPropertiesImportSelector implements ImportSelector { ConfigurationProperties annotation = AnnotationUtils.findAnnotation(type, ConfigurationProperties.class); if (annotation != null) { - return (StringUtils.hasLength(annotation.value()) ? annotation.value() - : annotation.prefix()); + return annotation.prefix(); } return ""; } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/scan/AbstractEntityScanRegistrar.java b/spring-boot/src/main/java/org/springframework/boot/context/scan/AbstractEntityScanRegistrar.java index 85cd34cf98c..61d026867c2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/scan/AbstractEntityScanRegistrar.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/scan/AbstractEntityScanRegistrar.java @@ -29,9 +29,7 @@ import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; /** * A baseĀ {@link ImportBeanDefinitionRegistrar} used to collect the packages to scan for a @@ -88,17 +86,9 @@ public abstract class AbstractEntityScanRegistrar protected Set getPackagesToScan(AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes .fromMap(metadata.getAnnotationAttributes(this.annotationType.getName())); - String[] value = attributes.getStringArray("value"); String[] basePackages = attributes.getStringArray("basePackages"); Class[] basePackageClasses = attributes.getClassArray("basePackageClasses"); - if (!ObjectUtils.isEmpty(value)) { - Assert.state(ObjectUtils.isEmpty(basePackages), - String.format( - "@%s basePackages and value attributes are mutually exclusive", - this.annotationType.getSimpleName())); - } Set packagesToScan = new LinkedHashSet(); - packagesToScan.addAll(Arrays.asList(value)); packagesToScan.addAll(Arrays.asList(basePackages)); for (Class basePackageClass : basePackageClasses) { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); diff --git a/spring-boot/src/main/java/org/springframework/boot/neo4j/NodeEntityScan.java b/spring-boot/src/main/java/org/springframework/boot/neo4j/NodeEntityScan.java index 7ee30f5831a..5f968f92764 100644 --- a/spring-boot/src/main/java/org/springframework/boot/neo4j/NodeEntityScan.java +++ b/spring-boot/src/main/java/org/springframework/boot/neo4j/NodeEntityScan.java @@ -26,6 +26,7 @@ import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.session.SessionFactory; import org.springframework.context.annotation.Import; +import org.springframework.core.annotation.AliasFor; /** * Configures the {@link SessionFactory} to scan for Neo4J {@link NodeEntity} classes in @@ -58,6 +59,7 @@ public @interface NodeEntityScan { * {@code @NodeEntityScan(basePackages="org.my.pkg")}. * @return the base packages to scan */ + @AliasFor("basePackages") String[] value() default {}; /** @@ -68,6 +70,7 @@ public @interface NodeEntityScan { * package names. * @return the base packages to scan */ + @AliasFor("value") String[] basePackages() default {}; /** diff --git a/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScan.java b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScan.java index 9e231c556e5..5b53de003cd 100644 --- a/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScan.java +++ b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScan.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -23,6 +23,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; +import org.springframework.core.annotation.AliasFor; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; /** @@ -55,6 +56,7 @@ public @interface EntityScan { * {@code @EntityScan(basePackages="org.my.pkg")}. * @return the base packages to scan */ + @AliasFor("basePackages") String[] value() default {}; /** @@ -65,6 +67,7 @@ public @interface EntityScan { * package names. * @return the base packages to scan */ + @AliasFor("value") String[] basePackages() default {}; /** diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java index e68ea97289d..6659d233c12 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScan.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -27,6 +27,7 @@ import javax.servlet.annotation.WebListener; import javax.servlet.annotation.WebServlet; import org.springframework.context.annotation.Import; +import org.springframework.core.annotation.AliasFor; /** * Enables scanning for Servlet components ({@link WebFilter filters}, {@link WebServlet @@ -55,6 +56,7 @@ public @interface ServletComponentScan { * {@code @ServletComponentScan(basePackages="org.my.pkg")}. * @return the base packages to scan */ + @AliasFor("basePackages") String[] value() default {}; /** @@ -65,6 +67,7 @@ public @interface ServletComponentScan { * package names. * @return the base packages to scan */ + @AliasFor("value") String[] basePackages() default {}; /** diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java index c4266f2bc77..f3c6b98ac7a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -28,14 +28,13 @@ import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; /** * {@link ImportBeanDefinitionRegistrar} used by {@link ServletComponentScan}. * * @author Andy Wilkinson + * @author Stephane Nicoll */ class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar { @@ -77,16 +76,9 @@ class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar { private Set getPackagesToScan(AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(ServletComponentScan.class.getName())); - String[] value = attributes.getStringArray("value"); String[] basePackages = attributes.getStringArray("basePackages"); Class[] basePackageClasses = attributes.getClassArray("basePackageClasses"); - if (!ObjectUtils.isEmpty(value)) { - Assert.state(ObjectUtils.isEmpty(basePackages), - "@ServletComponentScan basePackages and value attributes are" - + " mutually exclusive"); - } Set packagesToScan = new LinkedHashSet(); - packagesToScan.addAll(Arrays.asList(value)); packagesToScan.addAll(Arrays.asList(basePackages)); for (Class basePackageClass : basePackageClasses) { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); diff --git a/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScan.java b/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScan.java index af45607ccc1..0e0b5911d89 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScan.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScan.java @@ -23,6 +23,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; +import org.springframework.core.annotation.AliasFor; /** * EntityScan test annotation. @@ -35,8 +36,10 @@ import org.springframework.context.annotation.Import; @Import(TestEntityScanRegistrar.class) public @interface TestEntityScan { + @AliasFor("basePackages") String[] value() default {}; + @AliasFor("value") String[] basePackages() default {}; Class[] basePackageClasses() default {}; diff --git a/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScanTests.java b/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScanTests.java index 8cc8163120c..e25869fd967 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/scan/TestEntityScanTests.java @@ -25,6 +25,7 @@ import org.springframework.boot.context.scan.TestEntityScanRegistrar.TestFactory import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationConfigurationException; import static org.assertj.core.api.Assertions.assertThat; @@ -75,10 +76,11 @@ public class TestEntityScanTests { @Test public void valueAndBasePackagesThrows() throws Exception { - this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("@TestEntityScan basePackages and value " - + "attributes are mutually exclusive"); - this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class); + this.thrown.expect(AnnotationConfigurationException.class); + this.thrown.expectMessage("attribute 'value' and its alias 'basePackages' are declared"); + this.thrown.expectMessage("com.mycorp.entity"); + this.thrown.expectMessage("com.mycorp"); + new AnnotationConfigApplicationContext(ValueAndBasePackages.class); } @Test diff --git a/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java b/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java index 4b8fed1f094..29c36c78cd7 100644 --- a/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java @@ -23,6 +23,7 @@ import org.junit.rules.ExpectedException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationConfigurationException; import static org.assertj.core.api.Assertions.assertThat; @@ -74,14 +75,9 @@ public class ServletComponentScanRegistrarTests { @Test public void packagesConfiguredWithBothValueAndBasePackages() { - this.thrown.expect(IllegalStateException.class); - this.thrown.expectMessage("@ServletComponentScan basePackages and value" - + " attributes are mutually exclusive"); - this.context = new AnnotationConfigApplicationContext(ValueAndBasePackages.class); - ServletComponentRegisteringPostProcessor postProcessor = this.context - .getBean(ServletComponentRegisteringPostProcessor.class); - assertThat(postProcessor.getPackagesToScan()) - .contains(getClass().getPackage().getName()); + this.thrown.expect(AnnotationConfigurationException.class); + this.thrown.expectMessage("attribute 'value' and its alias 'basePackages' are declared"); + new AnnotationConfigApplicationContext(ValueAndBasePackages.class); } @Test