From 7e8b1ed40181ca224a62b8bed8c3e1911c66f9ad Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 14 Jun 2022 10:08:06 +0200 Subject: [PATCH] Polish Move hints registration to spring-beans, where the actual behavior is implemented. We chose not to move this to `AutowiredAnnotationBeanPostProcessor` for now, as this would require it to implement another AOT-related interface and add too much noise for this. See gh-28614 --- ...kartaAnnotationsRuntimeHintsRegistrar.java | 42 +++++++++++++ .../resources/META-INF/spring/aot.factories | 2 + ...AnnotationsRuntimeHintsRegistrarTests.java | 62 +++++++++++++++++++ spring-core/spring-core.gradle | 1 - .../CoreAnnotationsRuntimeHintsRegistrar.java | 5 -- ...AnnotationsRuntimeHintsRegistrarTests.java | 17 +---- 6 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 spring-beans/src/main/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrar.java create mode 100644 spring-beans/src/test/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrarTests.java diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrar.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrar.java new file mode 100644 index 00000000000..9988f50c499 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrar.java @@ -0,0 +1,42 @@ +/* + * 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. + * 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.beans.factory.annotation; + +import java.util.stream.Stream; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.support.RuntimeHintsUtils; +import org.springframework.util.ClassUtils; + +/** + * {@link RuntimeHintsRegistrar} for Jakarta annotations. + *

Hints are only registered if Jakarta inject is on the classpath. + * + * @author Brian Clozel + */ +class JakartaAnnotationsRuntimeHintsRegistrar implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + if (ClassUtils.isPresent("jakarta.inject.Inject", classLoader)) { + Stream.of("jakarta.inject.Inject", "jakarta.inject.Qualifier").forEach(annotationType -> + RuntimeHintsUtils.registerAnnotation(hints, ClassUtils.resolveClassName(annotationType, classLoader))); + } + } + +} diff --git a/spring-beans/src/main/resources/META-INF/spring/aot.factories b/spring-beans/src/main/resources/META-INF/spring/aot.factories index b95137025d8..cb5cd83550e 100644 --- a/spring-beans/src/main/resources/META-INF/spring/aot.factories +++ b/spring-beans/src/main/resources/META-INF/spring/aot.factories @@ -1,2 +1,4 @@ org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\ org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.beans.factory.annotation.JakartaAnnotationsRuntimeHintsRegistrar \ No newline at end of file diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrarTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrarTests.java new file mode 100644 index 00000000000..2816b9f2d48 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/JakartaAnnotationsRuntimeHintsRegistrarTests.java @@ -0,0 +1,62 @@ +/* + * 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. + * 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.beans.factory.annotation; + + +import jakarta.inject.Inject; +import jakarta.inject.Qualifier; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsPredicates; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.beans.factory.aot.AotFactoriesLoader; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.util.ClassUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JakartaAnnotationsRuntimeHintsRegistrar}. + * @author Brian Clozel + */ +class JakartaAnnotationsRuntimeHintsRegistrarTests { + + private final RuntimeHints hints = new RuntimeHints(); + + @BeforeEach + void setup() { + SpringFactoriesLoader.forResourceLocation(AotFactoriesLoader.FACTORIES_RESOURCE_LOCATION) + .load(RuntimeHintsRegistrar.class).forEach(registrar -> registrar + .registerHints(this.hints, ClassUtils.getDefaultClassLoader())); + } + + @Test + void jakartaInjectAnnotationHasHints() { + assertThat(RuntimeHintsPredicates.reflection().onType(Inject.class) + .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); + } + + @Test + void jakartaQualifierAnnotationHasHints() { + assertThat(RuntimeHintsPredicates.reflection().onType(Qualifier.class) + .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); + } + +} diff --git a/spring-core/spring-core.gradle b/spring-core/spring-core.gradle index c80a60849fa..d9ce7201e8d 100644 --- a/spring-core/spring-core.gradle +++ b/spring-core/spring-core.gradle @@ -60,7 +60,6 @@ dependencies { optional("io.smallrye.reactive:mutiny") optional("io.netty:netty-buffer") testImplementation("jakarta.annotation:jakarta.annotation-api") - testImplementation("jakarta.inject:jakarta.inject-api") testImplementation("jakarta.xml.bind:jakarta.xml.bind-api") testImplementation("com.google.code.findbugs:jsr305") testImplementation("com.fasterxml.woodstox:woodstox-core") diff --git a/spring-core/src/main/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrar.java index 30480b3c5ec..a8ad865e823 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrar.java @@ -23,7 +23,6 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.Order; import org.springframework.lang.Nullable; -import org.springframework.util.ClassUtils; /** * {@link RuntimeHintsRegistrar} for core annotations. @@ -37,10 +36,6 @@ class CoreAnnotationsRuntimeHintsRegistrar implements RuntimeHintsRegistrar { public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { Stream.of(AliasFor.class, Order.class).forEach(annotationType -> RuntimeHintsUtils.registerAnnotation(hints, annotationType)); - if (ClassUtils.isPresent("jakarta.inject.Inject", classLoader)) { - Stream.of("jakarta.inject.Inject", "jakarta.inject.Qualifier").forEach(annotationType -> - RuntimeHintsUtils.registerAnnotation(hints, ClassUtils.resolveClassName(annotationType, classLoader))); - } } } diff --git a/spring-core/src/test/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrarTests.java b/spring-core/src/test/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrarTests.java index 94d63183381..b3f6f67c78f 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrarTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/support/CoreAnnotationsRuntimeHintsRegistrarTests.java @@ -16,8 +16,6 @@ package org.springframework.aot.hint.support; -import jakarta.inject.Inject; -import jakarta.inject.Qualifier; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -39,11 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat; */ class CoreAnnotationsRuntimeHintsRegistrarTests { - private RuntimeHints hints; + private RuntimeHints hints = new RuntimeHints(); @BeforeEach void setup() { - this.hints = new RuntimeHints(); SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories") .load(RuntimeHintsRegistrar.class).forEach(registrar -> registrar .registerHints(this.hints, ClassUtils.getDefaultClassLoader())); @@ -61,16 +58,4 @@ class CoreAnnotationsRuntimeHintsRegistrarTests { .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); } - @Test - void jakartaInjectAnnotationHasHints() { - assertThat(RuntimeHintsPredicates.reflection().onType(Inject.class) - .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); - } - - @Test - void jakartaQualifierAnnotationHasHints() { - assertThat(RuntimeHintsPredicates.reflection().onType(Qualifier.class) - .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); - } - }