Browse Source

Polishing

pull/29492/head
Sam Brannen 2 years ago
parent
commit
eb91d21ada
  1. 2
      spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBeanRuntimeHints.java
  2. 19
      spring-context/src/main/java/org/springframework/context/annotation/ImportRuntimeHints.java
  3. 3
      spring-core/src/main/java/org/springframework/aot/hint/annotation/Reflective.java
  4. 4
      spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveProcessor.java
  5. 6
      spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java
  6. 18
      spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.java
  7. 4
      spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBindingProcessor.java
  8. 14
      spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessageMappingReflectiveProcessor.java
  9. 11
      spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java
  10. 6
      spring-test/src/main/java/org/springframework/test/context/aot/TestRuntimeHintsRegistrar.java
  11. 14
      spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerMappingReflectiveProcessor.java
  12. 1
      spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandlerReflectiveProcessor.java
  13. 3
      spring-web/src/main/java/org/springframework/web/service/annotation/HttpExchangeReflectiveProcessor.java

2
spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBeanRuntimeHints.java

@ -38,6 +38,7 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar { @@ -38,6 +38,7 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
if (!ClassUtils.isPresent(SCHEDULER_FACTORY_CLASS_NAME, classLoader)) {
@ -53,4 +54,5 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar { @@ -53,4 +54,5 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar {
private void typeHint(Builder typeHint) {
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS).onReachableType(SchedulerFactoryBean.class);
}
}

19
spring-context/src/main/java/org/springframework/context/annotation/ImportRuntimeHints.java

@ -29,7 +29,7 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -29,7 +29,7 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar;
* should be processed.
*
* <p>Unlike declaring {@link RuntimeHintsRegistrar} using
* {@code spring/aot.factories}, this annotation allows for more flexible
* {@code META-INF/spring/aot.factories}, this annotation allows for more flexible
* registration where it is only processed if the annotated component or bean
* method is actually registered in the bean factory. To illustrate this
* behavior, consider the following example:
@ -47,19 +47,24 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; @@ -47,19 +47,24 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar;
*
* }</pre>
*
* If the configuration class above is processed, {@code MyHints} will be
* contributed only if {@code MyCondition} matches. If it does not, and
* therefore {@code MyService} is not defined as a bean, the hints will
* <p>If the configuration class above is processed, {@code MyHints} will be
* contributed only if {@code MyCondition} matches. If the condition does not
* match, {@code MyService} will not be defined as a bean and the hints will
* not be processed either.
*
* <p>If several components refer to the same {@link RuntimeHintsRegistrar}
* implementation, it is invoked only once for a given bean factory
* processing.
* <p>{@code @ImportRuntimeHints} can also be applied to any test class that uses
* the <em>Spring TestContext Framework</em> to load an {@code ApplicationContext}.
*
* <p>If several components or test classes refer to the same {@link RuntimeHintsRegistrar}
* implementation, the registrar will only be invoked once for the given bean factory
* processing or test suite.
*
* @author Brian Clozel
* @author Stephane Nicoll
* @since 6.0
* @see org.springframework.aot.hint.RuntimeHints
* @see org.springframework.aot.hint.annotation.Reflective
* @see org.springframework.aot.hint.annotation.RegisterReflectionForBinding
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)

3
spring-core/src/main/java/org/springframework/aot/hint/annotation/Reflective.java

@ -29,7 +29,7 @@ import org.springframework.core.annotation.AliasFor; @@ -29,7 +29,7 @@ import org.springframework.core.annotation.AliasFor;
*
* <p>When present, either directly or as a meta-annotation, this annotation
* triggers the configured {@linkplain ReflectiveProcessor processors} against
* the annotated element. By default, a reflection hint is added on the
* the annotated element. By default, a reflection hint is registered for the
* annotated element so that it can be discovered and invoked if necessary.
*
* @author Stephane Nicoll
@ -37,6 +37,7 @@ import org.springframework.core.annotation.AliasFor; @@ -37,6 +37,7 @@ import org.springframework.core.annotation.AliasFor;
* @since 6.0
* @see SimpleReflectiveProcessor
* @see ReflectiveRuntimeHintsRegistrar
* @see RegisterReflectionForBinding @RegisterReflectionForBinding
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.CONSTRUCTOR,
ElementType.FIELD, ElementType.METHOD })

4
spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveProcessor.java

@ -24,8 +24,12 @@ import org.springframework.aot.hint.ReflectionHints; @@ -24,8 +24,12 @@ import org.springframework.aot.hint.ReflectionHints;
* Process an {@link AnnotatedElement} and register the necessary reflection
* hints for it.
*
* <p>{@code ReflectiveProcessor} implementations are registered via
* {@link Reflective#processors() @Reflective(processors = ...)}.
*
* @author Stephane Nicoll
* @since 6.0
* @see Reflective @Reflective
*/
public interface ReflectiveProcessor {

6
spring-core/src/main/java/org/springframework/aot/hint/annotation/ReflectiveRuntimeHintsRegistrar.java

@ -96,12 +96,12 @@ public class ReflectiveRuntimeHintsRegistrar { @@ -96,12 +96,12 @@ public class ReflectiveRuntimeHintsRegistrar {
.stream(Reflective.class)
.map(annotation -> annotation.getClassArray("value"))
.flatMap(Arrays::stream)
.map(type -> (Class<? extends ReflectiveProcessor>) type)
.distinct()
.map(type -> (Class<? extends ReflectiveProcessor>) type)
.map(processorClass -> this.processors.computeIfAbsent(processorClass, this::instantiateClass))
.toList();
ReflectiveProcessor processorToUse = (processors.size() == 1 ? processors.get(0)
: new DelegatingReflectiveProcessor(processors));
ReflectiveProcessor processorToUse = (processors.size() == 1 ? processors.get(0) :
new DelegatingReflectiveProcessor(processors));
return new Entry(element, processorToUse);
}

18
spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.java

@ -25,25 +25,24 @@ import java.lang.annotation.Target; @@ -25,25 +25,24 @@ import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Indicate that the classes specified in the annotation attributes require some
* Indicates that the classes specified in the annotation attributes require some
* reflection hints for binding or reflection-based serialization purposes. For each
* class specified, hints on constructors, fields, properties, record components,
* including types transitively used on properties and record components are registered.
* At least one class must be specified in the {@code value} or {@code classes} annotation
* attributes.
*
* <p>The annotated element can be a configuration class, for example:
* <p>The annotated element can be a configuration class &mdash; for example:
*
* <pre class="code">
* &#064;Configuration
* &#064;RegisterReflectionForBinding({ Foo.class, Bar.class })
* public class MyConfig {
*
* // ...
* }</pre>
*
* <p>The annotated element can also be any Spring bean class, constructor, field, or method.
* For example:
* <p>The annotated element can be any Spring bean class, constructor, field,
* or method &mdash; for example:
*
* <pre class="code">
* &#064;Service
@ -56,9 +55,13 @@ import org.springframework.core.annotation.AliasFor; @@ -56,9 +55,13 @@ import org.springframework.core.annotation.AliasFor;
*
* }</pre>
*
* <p>The annotated element can also be any test class that uses the <em>Spring
* TestContext Framework</em> to load an {@code ApplicationContext}.
*
* @author Sebastien Deleuze
* @since 6.0
* @see org.springframework.aot.hint.BindingReflectionHintsRegistrar
* @see Reflective @Reflective
*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ -67,10 +70,7 @@ import org.springframework.core.annotation.AliasFor; @@ -67,10 +70,7 @@ import org.springframework.core.annotation.AliasFor;
public @interface RegisterReflectionForBinding {
/**
* Classes for which reflection hints should be registered.
* <p>At least one class must be specified either via {@link #value} or
* {@link #classes}.
* @see #classes()
* Alias for {@link #classes()}.
*/
@AliasFor("classes")
Class<?>[] value() default {};

4
spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBindingProcessor.java

@ -36,9 +36,11 @@ public class RegisterReflectionForBindingProcessor implements ReflectiveProcesso @@ -36,9 +36,11 @@ public class RegisterReflectionForBindingProcessor implements ReflectiveProcesso
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
RegisterReflectionForBinding registerReflection = AnnotationUtils.getAnnotation(element, RegisterReflectionForBinding.class);
RegisterReflectionForBinding registerReflection =
AnnotationUtils.getAnnotation(element, RegisterReflectionForBinding.class);
if (registerReflection != null) {
Class<?>[] classes = registerReflection.classes();
Assert.state(classes.length != 0, () -> "A least one class should be specified in " +

14
spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessageMappingReflectiveProcessor.java

@ -34,12 +34,13 @@ import org.springframework.messaging.support.MessageHeaderAccessor; @@ -34,12 +34,13 @@ import org.springframework.messaging.support.MessageHeaderAccessor;
/**
* {@link ReflectiveProcessor} implementation for {@link MessageMapping}
* annotated types. On top of registering reflection hints for invoking
* annotated types. In addition to registering reflection hints for invoking
* the annotated method, this implementation handles:
*
* <ul>
* <li>Return types.</li>
* <li>Parameters identified as potential payload.</li>
* <li>{@link Message} parameters.</li>
* <li>Return types</li>
* <li>Parameters identified as potential payloads</li>
* <li>{@link Message} parameters</li>
* </ul>
*
* @author Sebastien Deleuze
@ -49,6 +50,7 @@ class MessageMappingReflectiveProcessor implements ReflectiveProcessor { @@ -49,6 +50,7 @@ class MessageMappingReflectiveProcessor implements ReflectiveProcessor {
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
if (element instanceof Class<?> type) {
@ -99,6 +101,8 @@ class MessageMappingReflectiveProcessor implements ReflectiveProcessor { @@ -99,6 +101,8 @@ class MessageMappingReflectiveProcessor implements ReflectiveProcessor {
@Nullable
protected Type getMessageType(MethodParameter parameter) {
MethodParameter nestedParameter = parameter.nested();
return (nestedParameter.getNestedParameterType() == nestedParameter.getParameterType() ? null : nestedParameter.getNestedParameterType());
return (nestedParameter.getNestedParameterType() == nestedParameter.getParameterType() ?
null : nestedParameter.getNestedParameterType());
}
}

11
spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java

@ -137,15 +137,20 @@ public class TestContextAotGenerator { @@ -137,15 +137,20 @@ public class TestContextAotGenerator {
mergedConfigMappings.add(mergedConfig, testClass);
collectRuntimeHintsRegistrarClasses(testClass, coreRuntimeHintsRegistrarClasses);
reflectiveRuntimeHintsRegistrar.registerRuntimeHints(this.runtimeHints, testClass);
this.testRuntimeHintsRegistrars.forEach(registrar ->
registrar.registerHints(this.runtimeHints, testClass, classLoader));
this.testRuntimeHintsRegistrars.forEach(registrar -> {
if (logger.isTraceEnabled()) {
logger.trace("Processing RuntimeHints contribution from class [%s]"
.formatted(registrar.getClass().getCanonicalName()));
}
registrar.registerHints(this.runtimeHints, testClass, classLoader);
});
});
coreRuntimeHintsRegistrarClasses.stream()
.map(BeanUtils::instantiateClass)
.forEach(registrar -> {
if (logger.isTraceEnabled()) {
logger.trace("Processing RuntimeHints contribution from test class [%s]"
logger.trace("Processing RuntimeHints contribution from class [%s]"
.formatted(registrar.getClass().getCanonicalName()));
}
registrar.registerHints(this.runtimeHints, classLoader);

6
spring-test/src/main/java/org/springframework/test/context/aot/TestRuntimeHintsRegistrar.java

@ -34,6 +34,12 @@ import org.springframework.aot.hint.RuntimeHints; @@ -34,6 +34,12 @@ import org.springframework.aot.hint.RuntimeHints;
* specific to particular test classes, favor implementing {@code RuntimeHintsRegistrar}
* over this API.
*
* <p>As an alternative to implementing and registering a {@code TestRuntimeHintsRegistrar},
* you may choose to annotate a test class with
* {@link org.springframework.aot.hint.annotation.Reflective @Reflective},
* {@link org.springframework.aot.hint.annotation.RegisterReflectionForBinding @RegisterReflectionForBinding},
* or {@link org.springframework.context.annotation.ImportRuntimeHints @ImportRuntimeHints}.
*
* @author Sam Brannen
* @since 6.0
* @see org.springframework.aot.hint.RuntimeHintsRegistrar

14
spring-web/src/main/java/org/springframework/web/bind/annotation/ControllerMappingReflectiveProcessor.java

@ -33,12 +33,13 @@ import org.springframework.stereotype.Controller; @@ -33,12 +33,13 @@ import org.springframework.stereotype.Controller;
/**
* {@link ReflectiveProcessor} implementation for {@link Controller} and
* controller-specific annotated methods. On top of registering reflection
* controller-specific annotated methods. In addition to registering reflection
* hints for invoking the annotated method, this implementation handles:
*
* <ul>
* <li>Return types annotated with {@link ResponseBody}.</li>
* <li>Parameters annotated with {@link RequestBody}.</li>
* <li>{@link HttpEntity} return type and parameters.</li>
* <li>Return types annotated with {@link ResponseBody}</li>
* <li>Parameters annotated with {@link RequestBody}</li>
* <li>{@link HttpEntity} return types and parameters</li>
* </ul>
*
* @author Stephane Nicoll
@ -49,6 +50,7 @@ class ControllerMappingReflectiveProcessor implements ReflectiveProcessor { @@ -49,6 +50,7 @@ class ControllerMappingReflectiveProcessor implements ReflectiveProcessor {
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
if (element instanceof Class<?> type) {
@ -98,8 +100,8 @@ class ControllerMappingReflectiveProcessor implements ReflectiveProcessor { @@ -98,8 +100,8 @@ class ControllerMappingReflectiveProcessor implements ReflectiveProcessor {
@Nullable
private Type getHttpEntityType(MethodParameter parameter) {
MethodParameter nestedParameter = parameter.nested();
return (nestedParameter.getNestedParameterType() == nestedParameter.getParameterType()
? null : nestedParameter.getNestedParameterType());
return (nestedParameter.getNestedParameterType() == nestedParameter.getParameterType() ?
null : nestedParameter.getNestedParameterType());
}
}

1
spring-web/src/main/java/org/springframework/web/bind/annotation/ExceptionHandlerReflectiveProcessor.java

@ -37,4 +37,5 @@ class ExceptionHandlerReflectiveProcessor extends ControllerMappingReflectivePro @@ -37,4 +37,5 @@ class ExceptionHandlerReflectiveProcessor extends ControllerMappingReflectivePro
}
super.registerReturnTypeHints(hints, returnTypeParameter);
}
}

3
spring-web/src/main/java/org/springframework/web/service/annotation/HttpExchangeReflectiveProcessor.java

@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RequestBody; @@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RequestBody;
/**
* {@link ReflectiveProcessor} implementation for {@link HttpExchange @HttpExchange}
* and annotated methods. On top of registering reflection hints for invoking
* annotated methods. In addition to registering reflection hints for invoking
* the annotated method, this implementation handles reflection-based
* binding for return types and parameters annotated with {@link RequestBody}.
*
@ -40,6 +40,7 @@ class HttpExchangeReflectiveProcessor implements ReflectiveProcessor { @@ -40,6 +40,7 @@ class HttpExchangeReflectiveProcessor implements ReflectiveProcessor {
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) {
if (element instanceof Method method) {

Loading…
Cancel
Save