diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java index f5be7dd77757..7afc47cbd20c 100644 --- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java +++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java @@ -16,11 +16,14 @@ package org.springframework.test.context.bean.override; +import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; + /** * Mark a composed annotation as eligible for Bean Override processing. * @@ -31,10 +34,13 @@ * expected that it has a {@link Target} of {@link ElementType#FIELD FIELD}. * * @author Simon Baslé + * @author Sam Brannen * @since 6.2 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) +@Documented +@Reflective(BeanOverrideReflectiveProcessor.class) public @interface BeanOverride { /** diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideReflectiveProcessor.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideReflectiveProcessor.java new file mode 100644 index 000000000000..787fcd0ff3ce --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideReflectiveProcessor.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2024 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.test.context.bean.override; + +import java.lang.reflect.AnnotatedElement; + +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.annotation.ReflectiveProcessor; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; + +import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_CONSTRUCTORS; + +/** + * {@link ReflectiveProcessor} that processes {@link BeanOverride @BeanOverride} + * annotations. + * + * @author Sam Brannen + * @since 6.2 + */ +class BeanOverrideReflectiveProcessor implements ReflectiveProcessor { + + @Override + public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) { + MergedAnnotations.from(element) + .get(BeanOverride.class) + .synthesize(MergedAnnotation::isPresent) + .map(BeanOverride::value) + .ifPresent(clazz -> hints.registerType(clazz, INVOKE_DECLARED_CONSTRUCTORS)); + } + +}