From 18a87eaf2a5c73b0d18a7b6cf64e32fcf0ab6eb9 Mon Sep 17 00:00:00 2001 From: abilan Date: Thu, 17 Nov 2022 13:35:35 -0500 Subject: [PATCH] Register Lifecycle methods for AbstractEndpoint * Also register `Pausable` explicitly and remove its `@Reflective`. This type is needed for Control Bus SpEL execution, but it might not be available at runtime because not all endpoints implement it --- .../integration/aot/CoreRuntimeHints.java | 15 ++++++++++----- .../integration/core/Pausable.java | 4 ---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java b/spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java index e5f02e8d01..826d28809b 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java @@ -27,6 +27,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; import org.springframework.aop.framework.AopProxyUtils; +import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.ProxyHints; import org.springframework.aot.hint.ReflectionHints; @@ -35,7 +36,6 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.SerializationHints; import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.config.BeanExpressionContext; -import org.springframework.context.Lifecycle; import org.springframework.context.SmartLifecycle; import org.springframework.integration.aggregator.MessageGroupProcessor; import org.springframework.integration.context.IntegrationContextUtils; @@ -44,7 +44,9 @@ import org.springframework.integration.core.GenericHandler; import org.springframework.integration.core.GenericSelector; import org.springframework.integration.core.GenericTransformer; import org.springframework.integration.core.MessageSource; +import org.springframework.integration.core.Pausable; import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.endpoint.AbstractEndpoint; import org.springframework.integration.gateway.MethodArgsHolder; import org.springframework.integration.gateway.RequestReplyExchanger; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; @@ -63,6 +65,7 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.PollableChannel; import org.springframework.messaging.support.ErrorMessage; import org.springframework.messaging.support.GenericMessage; +import org.springframework.util.ReflectionUtils; /** * {@link RuntimeHintsRegistrar} for Spring Integration core module. @@ -88,7 +91,7 @@ class CoreRuntimeHints implements RuntimeHintsRegistrar { MethodArgsHolder.class, AbstractReplyProducingMessageHandler.RequestHandler.class, ExpressionEvaluatingRoutingSlipRouteStrategy.RequestAndReply.class, - Lifecycle.class) + Pausable.class) .forEach(type -> reflectionHints.registerType(type, MemberCategory.INVOKE_PUBLIC_METHODS)); reflectionHints.registerType(JsonPathUtils.class, @@ -100,12 +103,14 @@ class CoreRuntimeHints implements RuntimeHintsRegistrar { reflectionHints.registerTypeIfPresent(classLoader, "org.springframework.integration.xml.xpath.XPathUtils", MemberCategory.INVOKE_PUBLIC_METHODS); - Stream.of( - "kotlin.jvm.functions.Function0", - "kotlin.jvm.functions.Function1") + Stream.of("kotlin.jvm.functions.Function0", "kotlin.jvm.functions.Function1") .forEach(type -> reflectionHints.registerTypeIfPresent(classLoader, type, MemberCategory.INVOKE_PUBLIC_METHODS)); + Stream.of("start", "stop", "isRunning") + .flatMap((name) -> Stream.ofNullable(ReflectionUtils.findMethod(AbstractEndpoint.class, name))) + .forEach(method -> reflectionHints.registerMethod(method, ExecutableMode.INVOKE)); + hints.resources().registerPattern("META-INF/spring.integration.properties"); SerializationHints serializationHints = hints.serialization(); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/core/Pausable.java b/spring-integration-core/src/main/java/org/springframework/integration/core/Pausable.java index 68d6b685c7..4fa2c89579 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/core/Pausable.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/core/Pausable.java @@ -16,7 +16,6 @@ package org.springframework.integration.core; -import org.springframework.aot.hint.annotation.Reflective; import org.springframework.integration.support.management.ManageableLifecycle; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedOperation; @@ -38,14 +37,12 @@ public interface Pausable extends ManageableLifecycle { * Pause the endpoint. */ @ManagedOperation(description = "Pause the component") - @Reflective void pause(); /** * Resume the endpoint if paused. */ @ManagedOperation(description = "Resume the component") - @Reflective void resume(); /** @@ -54,7 +51,6 @@ public interface Pausable extends ManageableLifecycle { * @since 5.4 */ @ManagedAttribute(description = "Is the component paused?") - @Reflective default boolean isPaused() { throw new UnsupportedOperationException("This component does not implement this method"); }