From 69f23095b810615862336d35d878dda63f7b4fca Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 2 Sep 2022 11:55:22 +0200 Subject: [PATCH] Deprecate SynthesizedAnnotation and related methods Since Spring no longer adds the SynthesizedAnnotation interface to the JDK dynamic proxy used to synthesize an annotation, this commit officially deprecates SynthesizedAnnotation and related methods in RuntimeHintsUtils. See gh-29041, gh-29054 Closes gh-29053 --- .../BeanFactoryAnnotationsRuntimeHints.java | 1 + .../annotation/ReflectiveRuntimeHintsRegistrar.java | 1 + .../aot/hint/support/RuntimeHintsUtils.java | 11 ++++++++--- .../core/annotation/SynthesizedAnnotation.java | 6 +++++- .../ReflectiveRuntimeHintsRegistrarTests.java | 7 ++++--- .../aot/hint/support/RuntimeHintsUtilsTests.java | 10 ++++++++-- .../annotation/MessagingAnnotationsRuntimeHints.java | 2 ++ .../simp/annotation/SimpAnnotationsRuntimeHints.java | 2 ++ .../context/aot/hint/TestContextRuntimeHints.java | 2 +- .../context/aot/TestContextAotGeneratorTests.java | 5 +++-- .../annotation/TransactionRuntimeHints.java | 1 + .../WebAnnotationsRuntimeHintsRegistrar.java | 1 + 12 files changed, 37 insertions(+), 12 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationsRuntimeHints.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationsRuntimeHints.java index f7cf4c4c296..ec7ad57fdb8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationsRuntimeHints.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/BeanFactoryAnnotationsRuntimeHints.java @@ -30,6 +30,7 @@ import org.springframework.lang.Nullable; class BeanFactoryAnnotationsRuntimeHints implements RuntimeHintsRegistrar { @Override + @SuppressWarnings("deprecation") public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { RuntimeHintsUtils.registerSynthesizedAnnotation(hints, Qualifier.class); } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java index 6c24c8e76e2..a8bcceb292a 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java @@ -66,6 +66,7 @@ public class ReflectiveRuntimeHintsRegistrar { }); } + @SuppressWarnings("deprecation") private void registerAnnotationIfNecessary(RuntimeHints hints, AnnotatedElement element) { MergedAnnotation reflectiveAnnotation = MergedAnnotations.from(element) .get(Reflective.class); diff --git a/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java b/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java index 6f687889a4f..9668f1d891a 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/support/RuntimeHintsUtils.java @@ -24,7 +24,6 @@ import org.springframework.aot.hint.TypeHint; import org.springframework.aot.hint.TypeHint.Builder; import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.SynthesizedAnnotation; /** * Utility methods for runtime hints support code. @@ -49,7 +48,7 @@ public abstract class RuntimeHintsUtils { * at runtime. * @param hints the {@link RuntimeHints} instance to use * @param annotationType the annotation type - * @deprecated as annotation attributes are visible without additional hints + * @deprecated For removal prior to Spring Framework 6.0 */ @Deprecated public static void registerAnnotation(RuntimeHints hints, Class annotationType) { @@ -69,9 +68,13 @@ public abstract class RuntimeHintsUtils { * that determines if the hints are required. * @param hints the {@link RuntimeHints} instance to use * @param annotationType the annotation type + * @deprecated For removal prior to Spring Framework 6.0 */ + @Deprecated + @SuppressWarnings("deprecation") public static void registerSynthesizedAnnotation(RuntimeHints hints, Class annotationType) { - hints.proxies().registerJdkProxy(annotationType, SynthesizedAnnotation.class); + hints.proxies().registerJdkProxy(annotationType, + org.springframework.core.annotation.SynthesizedAnnotation.class); } /** @@ -80,7 +83,9 @@ public abstract class RuntimeHintsUtils { * @param hints the {@link RuntimeHints} instance to use * @param annotation the annotation * @see #registerSynthesizedAnnotation(RuntimeHints, Class) + * @deprecated For removal prior to Spring Framework 6.0 */ + @Deprecated public static void registerAnnotationIfNecessary(RuntimeHints hints, MergedAnnotation annotation) { if (annotation.isSynthesizable()) { registerSynthesizedAnnotation(hints, annotation.getType()); diff --git a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedAnnotation.java index 6fd52f726c3..ceb8c9ae138 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedAnnotation.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2022 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,10 @@ package org.springframework.core.annotation; * * @author Sam Brannen * @since 4.2 + * @deprecated For removal prior to Spring Framework 6.0; use + * {@link AnnotationUtils#isSynthesizedAnnotation(java.lang.annotation.Annotation)} + * instead. */ +@Deprecated public interface SynthesizedAnnotation { } diff --git a/spring-core/src/test/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrarTests.java b/spring-core/src/test/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrarTests.java index 2e515a80401..5c1057d3bb2 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrarTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrarTests.java @@ -31,7 +31,6 @@ import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.core.annotation.AliasFor; -import org.springframework.core.annotation.SynthesizedAnnotation; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -95,11 +94,13 @@ class ReflectiveRuntimeHintsRegistrarTests { } @Test + @SuppressWarnings("deprecation") void shouldRegisterAnnotationProxy() { process(SampleMethodMetaAnnotatedBeanWithAlias.class); RuntimeHints runtimeHints = this.runtimeHints; - assertThat(RuntimeHintsPredicates.proxies().forInterfaces( - SampleInvoker.class, SynthesizedAnnotation.class)).accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.proxies() + .forInterfaces(SampleInvoker.class, org.springframework.core.annotation.SynthesizedAnnotation.class)) + .accepts(runtimeHints); } @Test diff --git a/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java b/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java index 919ac575309..ca4f576e6ea 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/support/RuntimeHintsUtilsTests.java @@ -28,7 +28,6 @@ import org.springframework.aot.hint.TypeReference; import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.SynthesizedAnnotation; import static org.assertj.core.api.Assertions.assertThat; @@ -43,6 +42,7 @@ class RuntimeHintsUtilsTests { private final RuntimeHints hints = new RuntimeHints(); @Test + @SuppressWarnings("deprecation") void registerSynthesizedAnnotation() { RuntimeHintsUtils.registerSynthesizedAnnotation(this.hints, SampleInvoker.class); assertThat(this.hints.proxies().jdkProxies()).singleElement() @@ -50,6 +50,7 @@ class RuntimeHintsUtilsTests { } @Test + @SuppressWarnings("deprecation") void registerAnnotationIfNecessaryWithNonSynthesizedAnnotation() throws NoSuchFieldException { MergedAnnotation annotation = MergedAnnotations .from(TestBean.class.getField("sampleInvoker")).get(SampleInvoker.class); @@ -58,6 +59,7 @@ class RuntimeHintsUtilsTests { } @Test + @SuppressWarnings("deprecation") void registerAnnotationIfNecessaryWithLocalAliases() throws NoSuchFieldException { MergedAnnotation annotation = MergedAnnotations .from(TestBean.class.getField("localMapping")).get(LocalMapping.class); @@ -67,6 +69,7 @@ class RuntimeHintsUtilsTests { } @Test + @SuppressWarnings("deprecation") void registerAnnotationIfNecessaryWithMetaAttributeOverride() throws NoSuchFieldException { MergedAnnotation annotation = MergedAnnotations .from(TestBean.class.getField("retryInvoker")).get(SampleInvoker.class); @@ -76,6 +79,7 @@ class RuntimeHintsUtilsTests { } @Test + @SuppressWarnings("deprecation") void registerAnnotationIfNecessaryWithSynthesizedAttribute() throws NoSuchFieldException { MergedAnnotation annotation = MergedAnnotations .from(TestBean.class.getField("retryContainer")).get(RetryContainer.class); @@ -84,9 +88,11 @@ class RuntimeHintsUtilsTests { .satisfies(annotationProxy(RetryContainer.class)); } + @SuppressWarnings("deprecation") private Consumer annotationProxy(Class type) { return jdkProxyHint -> assertThat(jdkProxyHint.getProxiedInterfaces()) - .containsExactly(TypeReference.of(type), TypeReference.of(SynthesizedAnnotation.class)); + .containsExactly(TypeReference.of(type), + TypeReference.of(org.springframework.core.annotation.SynthesizedAnnotation.class)); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessagingAnnotationsRuntimeHints.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessagingAnnotationsRuntimeHints.java index 5d0dc97978f..0b36fba3492 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessagingAnnotationsRuntimeHints.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessagingAnnotationsRuntimeHints.java @@ -34,8 +34,10 @@ import org.springframework.stereotype.Controller; public class MessagingAnnotationsRuntimeHints implements RuntimeHintsRegistrar { @Override + @SuppressWarnings("deprecation") public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { Stream.of(Controller.class, Header.class, Headers.class, Payload.class).forEach(annotationType -> RuntimeHintsUtils.registerSynthesizedAnnotation(hints, annotationType)); } + } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/SimpAnnotationsRuntimeHints.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/SimpAnnotationsRuntimeHints.java index 1ea02f7b0c3..195489373ba 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/SimpAnnotationsRuntimeHints.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/SimpAnnotationsRuntimeHints.java @@ -30,7 +30,9 @@ import org.springframework.aot.hint.support.RuntimeHintsUtils; public class SimpAnnotationsRuntimeHints implements RuntimeHintsRegistrar { @Override + @SuppressWarnings("deprecation") public void registerHints(RuntimeHints hints, ClassLoader classLoader) { RuntimeHintsUtils.registerSynthesizedAnnotation(hints, SendToUser.class); } + } diff --git a/spring-test/src/main/java/org/springframework/test/context/aot/hint/TestContextRuntimeHints.java b/spring-test/src/main/java/org/springframework/test/context/aot/hint/TestContextRuntimeHints.java index 6eb52f5d6e3..7b00ebe218e 100644 --- a/spring-test/src/main/java/org/springframework/test/context/aot/hint/TestContextRuntimeHints.java +++ b/spring-test/src/main/java/org/springframework/test/context/aot/hint/TestContextRuntimeHints.java @@ -169,7 +169,7 @@ class TestContextRuntimeHints implements RuntimeHintsRegistrar { } @SafeVarargs - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "deprecation" }) private static void registerSynthesizedAnnotations(RuntimeHints runtimeHints, Class... annotationTypes) { for (Class annotationType : annotationTypes) { registerAnnotation(runtimeHints.reflection(), annotationType); diff --git a/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java b/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java index 148fc58f4a1..a858fbc7361 100644 --- a/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java @@ -36,7 +36,6 @@ import org.springframework.aot.test.generator.compile.TestCompiler; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.annotation.SynthesizedAnnotation; import org.springframework.javapoet.ClassName; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.aot.samples.basic.BasicSpringJupiterSharedConfigTests; @@ -210,9 +209,11 @@ class TestContextAotGeneratorTests extends AbstractAotTests { .anySatisfy(annotationProxy(annotationType)); } + @SuppressWarnings("deprecation") private static Consumer annotationProxy(Class type) { return jdkProxyHint -> assertThat(jdkProxyHint.getProxiedInterfaces()) - .containsExactly(TypeReference.of(type), TypeReference.of(SynthesizedAnnotation.class)); + .containsExactly(TypeReference.of(type), + TypeReference.of(org.springframework.core.annotation.SynthesizedAnnotation.class)); } @Test diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionRuntimeHints.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionRuntimeHints.java index 23a9ab4d26d..e6b267a9f62 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionRuntimeHints.java +++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/TransactionRuntimeHints.java @@ -35,6 +35,7 @@ import org.springframework.transaction.TransactionDefinition; class TransactionRuntimeHints implements RuntimeHintsRegistrar { @Override + @SuppressWarnings("deprecation") public void registerHints(RuntimeHints hints, ClassLoader classLoader) { RuntimeHintsUtils.registerSynthesizedAnnotation(hints, Transactional.class); hints.reflection().registerTypes(TypeReference.listOf( diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/WebAnnotationsRuntimeHintsRegistrar.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/WebAnnotationsRuntimeHintsRegistrar.java index df8886f40df..02bbd432897 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/WebAnnotationsRuntimeHintsRegistrar.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/WebAnnotationsRuntimeHintsRegistrar.java @@ -34,6 +34,7 @@ import org.springframework.stereotype.Controller; public final class WebAnnotationsRuntimeHintsRegistrar implements RuntimeHintsRegistrar { @Override + @SuppressWarnings("deprecation") public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { Stream.of(Controller.class, ControllerAdvice.class, CookieValue.class, CrossOrigin.class, MatrixVariable.class, ModelAttribute.class,