From 7031964e4940ae0c6d309571d60adc1ccee48a4d Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 6 May 2019 09:46:11 -0700 Subject: [PATCH] Deprecate StandardMetadata constructors Deprecate the public `StandardMetadata` constructors to make it clearer that these classes should not be instantiated directly. A new `AnnotationMetadata.introspect` factory method has been added which can now be used to obtain instances. This change will allow use to make the constructors package private and drop the `nestedAnnotationsAsMap` parameter in a future release. Closes gh-22906 --- .../AnnotatedGenericBeanDefinition.java | 4 ++-- .../context/annotation/ConfigurationClass.java | 7 +++---- .../annotation/ConfigurationClassParser.java | 2 +- .../annotation/ConfigurationClassUtils.java | 3 +-- .../core/type/AnnotationMetadata.java | 12 ++++++++++++ .../core/type/StandardAnnotationMetadata.java | 14 ++++++++++++++ .../core/type/StandardClassMetadata.java | 4 +++- .../core/type/StandardMethodMetadata.java | 4 ++++ .../core/type/AnnotationMetadataTests.java | 16 +++++++++------- .../type/StandardAnnotationMetadataTests.java | 1 + .../StandardClassMetadataMemberClassTests.java | 3 ++- .../core/type/StandardMethodMetadataTests.java | 2 +- 12 files changed, 53 insertions(+), 19 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java index ae4fd2be88..c0cf85a172 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -55,7 +55,7 @@ public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implem */ public AnnotatedGenericBeanDefinition(Class beanClass) { setBeanClass(beanClass); - this.metadata = new StandardAnnotationMetadata(beanClass, true); + this.metadata = AnnotationMetadata.introspect(beanClass); } /** diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index f6e57eb483..6b747b126f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -29,7 +29,6 @@ import org.springframework.beans.factory.support.BeanDefinitionReader; import org.springframework.core.io.DescriptiveResource; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -104,7 +103,7 @@ final class ConfigurationClass { */ public ConfigurationClass(Class clazz, String beanName) { Assert.notNull(beanName, "Bean name must not be null"); - this.metadata = new StandardAnnotationMetadata(clazz, true); + this.metadata = AnnotationMetadata.introspect(clazz); this.resource = new DescriptiveResource(clazz.getName()); this.beanName = beanName; } @@ -118,7 +117,7 @@ final class ConfigurationClass { * @since 3.1.1 */ public ConfigurationClass(Class clazz, @Nullable ConfigurationClass importedBy) { - this.metadata = new StandardAnnotationMetadata(clazz, true); + this.metadata = AnnotationMetadata.introspect(clazz); this.resource = new DescriptiveResource(clazz.getName()); this.importedBy.add(importedBy); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index 6cc2f1786d..a3f14134a8 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -913,7 +913,7 @@ class ConfigurationClassParser { public SourceClass(Object source) { this.source = source; if (source instanceof Class) { - this.metadata = new StandardAnnotationMetadata((Class) source, true); + this.metadata = AnnotationMetadata.introspect((Class) source); } else { this.metadata = ((MetadataReader) source).getAnnotationMetadata(); diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java index 322a96f2b6..3758084c31 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassUtils.java @@ -36,7 +36,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.lang.Nullable; @@ -106,7 +105,7 @@ abstract class ConfigurationClassUtils { EventListenerFactory.class.isAssignableFrom(beanClass)) { return false; } - metadata = new StandardAnnotationMetadata(beanClass, true); + metadata = AnnotationMetadata.introspect(beanClass); } else { try { diff --git a/spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java b/spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java index 3bd7f8c6c8..66592ba7ea 100644 --- a/spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/AnnotationMetadata.java @@ -115,4 +115,16 @@ public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata */ Set getAnnotatedMethods(String annotationName); + + /** + * Factory method to create a new {@link AnnotationMetadata} instance + * for the given class using standard reflection. + * @param type the class to introspect + * @return a new {@link AnnotationMetadata} instance + * @since 5.2 + */ + static AnnotationMetadata introspect(Class type) { + return StandardAnnotationMetadata.from(type); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java index dcf4a7e9a1..22212e83e5 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.java @@ -26,6 +26,7 @@ import java.util.Set; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationFilter; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.core.annotation.RepeatableContainers; @@ -56,7 +57,9 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements * Create a new {@code StandardAnnotationMetadata} wrapper for the given Class. * @param introspectedClass the Class to introspect * @see #StandardAnnotationMetadata(Class, boolean) + * @deprecated since 5.2 in favor of the factory method {@link AnnotationMetadata#introspect(Class)} */ + @Deprecated public StandardAnnotationMetadata(Class introspectedClass) { this(introspectedClass, false); } @@ -71,7 +74,12 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements * {@link org.springframework.core.annotation.AnnotationAttributes} for compatibility * with ASM-based {@link AnnotationMetadata} implementations * @since 3.1.1 + * @deprecated since 5.2 in favor of the factory method {@link AnnotationMetadata#introspect(Class)}. + * Use {@link MergedAnnotation#asMap(org.springframework.core.annotation.MergedAnnotation.Adapt...) MergedAnnotation.asMap} + * from {@link #getAnnotations()} rather than {@link #getAnnotationAttributes(String)} + * if {@code nestedAnnotationsAsMap} is {@code false} */ + @Deprecated public StandardAnnotationMetadata(Class introspectedClass, boolean nestedAnnotationsAsMap) { super(introspectedClass); this.mergedAnnotations = MergedAnnotations.from(introspectedClass, @@ -138,6 +146,7 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements } @Override + @SuppressWarnings("deprecation") public Set getAnnotatedMethods(String annotationName) { Set annotatedMethods = null; if (AnnotationUtils.isCandidateClass(getIntrospectedClass(), annotationName)) { @@ -164,4 +173,9 @@ public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotatedElementUtils.isAnnotated(method, annotationName); } + + static AnnotationMetadata from(Class introspectedClass) { + return new StandardAnnotationMetadata(introspectedClass, true); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java index 0b4fe333de..ae9c2961e6 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -38,7 +38,9 @@ public class StandardClassMetadata implements ClassMetadata { /** * Create a new StandardClassMetadata wrapper for the given Class. * @param introspectedClass the Class to introspect + * @deprecated since 5.2 in favor of {@link StandardAnnotationMetadata} */ + @Deprecated public StandardClassMetadata(Class introspectedClass) { Assert.notNull(introspectedClass, "Class must not be null"); this.introspectedClass = introspectedClass; diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java index 42de7b6d50..b649359ecb 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java @@ -51,7 +51,9 @@ public class StandardMethodMetadata implements MethodMetadata { /** * Create a new StandardMethodMetadata wrapper for the given Method. * @param introspectedMethod the Method to introspect + * @deprecated since 5.2 in favor of obtaining instances via {@link AnnotationMetadata} */ + @Deprecated public StandardMethodMetadata(Method introspectedMethod) { this(introspectedMethod, false); } @@ -66,7 +68,9 @@ public class StandardMethodMetadata implements MethodMetadata { * {@link org.springframework.core.annotation.AnnotationAttributes} for compatibility * with ASM-based {@link AnnotationMetadata} implementations * @since 3.1.1 + * @deprecated since 5.2 in favor of obtaining instances via {@link AnnotationMetadata} */ + @Deprecated public StandardMethodMetadata(Method introspectedMethod, boolean nestedAnnotationsAsMap) { Assert.notNull(introspectedMethod, "Method must not be null"); this.introspectedMethod = introspectedMethod; diff --git a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java index 5cbd75bbee..a78f97ba54 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java @@ -55,7 +55,7 @@ public class AnnotationMetadataTests { @Test public void standardAnnotationMetadata() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponent.class); doTestAnnotationInfo(metadata); doTestMethodAnnotationInfo(metadata); } @@ -71,7 +71,7 @@ public class AnnotationMetadataTests { @Test public void standardAnnotationMetadataForSubclass() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponentSubClass.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotatedComponentSubClass.class); doTestSubClassAnnotationInfo(metadata); } @@ -107,7 +107,7 @@ public class AnnotationMetadataTests { @Test public void standardAnnotationMetadataForInterface() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotationMetadata.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(AnnotationMetadata.class); doTestMetadataForInterfaceClass(metadata); } @@ -135,7 +135,7 @@ public class AnnotationMetadataTests { @Test public void standardAnnotationMetadataForAnnotation() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(Component.class, true); + AnnotationMetadata metadata = AnnotationMetadata.introspect(Component.class); doTestMetadataForAnnotationClass(metadata); } @@ -174,6 +174,7 @@ public class AnnotationMetadataTests { * 'true' as is done in the main test above. */ @Test + @Deprecated public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() { AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class); AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName()); @@ -182,6 +183,7 @@ public class AnnotationMetadataTests { } @Test + @Deprecated public void metaAnnotationOverridesUsingStandardAnnotationMetadata() { AnnotationMetadata metadata = new StandardAnnotationMetadata(ComposedConfigurationWithAttributeOverridesClass.class); assertMetaAnnotationOverrides(metadata); @@ -209,7 +211,7 @@ public class AnnotationMetadataTests { @Test // SPR-11649 public void multipleAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedAnnotationsClass.class); + AnnotationMetadata metadata = AnnotationMetadata.introspect(NamedAnnotationsClass.class); assertMultipleAnnotationsWithIdenticalAttributeNames(metadata); } @@ -223,7 +225,7 @@ public class AnnotationMetadataTests { @Test // SPR-11649 public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationClass.class); + AnnotationMetadata metadata = AnnotationMetadata.introspect(NamedComposedAnnotationClass.class); assertMultipleAnnotationsWithIdenticalAttributeNames(metadata); } @@ -237,7 +239,7 @@ public class AnnotationMetadataTests { @Test public void inheritedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() { - AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationExtended.class); + AnnotationMetadata metadata = AnnotationMetadata.introspect(NamedComposedAnnotationExtended.class); assertFalse(metadata.hasAnnotation(NamedComposedAnnotation.class.getName())); } diff --git a/spring-core/src/test/java/org/springframework/core/type/StandardAnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/StandardAnnotationMetadataTests.java index 328419e882..325ecee6e4 100644 --- a/spring-core/src/test/java/org/springframework/core/type/StandardAnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/StandardAnnotationMetadataTests.java @@ -24,6 +24,7 @@ package org.springframework.core.type; public class StandardAnnotationMetadataTests extends AbstractAnnotationMetadataTests { @Override + @SuppressWarnings("deprecation") protected AnnotationMetadata get(Class source) { return new StandardAnnotationMetadata(source); } diff --git a/spring-core/src/test/java/org/springframework/core/type/StandardClassMetadataMemberClassTests.java b/spring-core/src/test/java/org/springframework/core/type/StandardClassMetadataMemberClassTests.java index 85210cfa6e..3e6260b47a 100644 --- a/spring-core/src/test/java/org/springframework/core/type/StandardClassMetadataMemberClassTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/StandardClassMetadataMemberClassTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2019 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. @@ -25,6 +25,7 @@ public class StandardClassMetadataMemberClassTests extends AbstractClassMetadataMemberClassTests { @Override + @SuppressWarnings("deprecation") public ClassMetadata getClassMetadataFor(Class clazz) { return new StandardClassMetadata(clazz); } diff --git a/spring-core/src/test/java/org/springframework/core/type/StandardMethodMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/StandardMethodMetadataTests.java index ebfe4ba87c..b55fa6f08e 100644 --- a/spring-core/src/test/java/org/springframework/core/type/StandardMethodMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/StandardMethodMetadataTests.java @@ -25,7 +25,7 @@ public class StandardMethodMetadataTests extends AbstractMethodMetadataTests { @Override protected AnnotationMetadata get(Class source) { - return new StandardAnnotationMetadata(source); + return AnnotationMetadata.introspect(source); } }