This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 37fb8c35ed8ea4fdbfbca284148117aba79d07ed Author: Claus Ibsen <[email protected]> AuthorDate: Fri Aug 30 15:16:05 2024 +0200 CAMEL-21140: camel-core - Add init/destroy method support for registry bind --- .../main/java/org/apache/camel/BindToRegistry.java | 10 ++++++---- .../impl/engine/CamelPostProcessorHelper.java | 23 ++++++++++++++++++++++ .../impl/engine/DefaultCamelBeanPostProcessor.java | 18 ++++++++--------- .../camel/support/scan/PackageScanHelper.java | 5 ++++- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java b/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java index 3c68788d609..32e88128e6f 100644 --- a/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java +++ b/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java @@ -50,22 +50,24 @@ public @interface BindToRegistry { /** * Whether to create the bean instance lazy (on-demand) instead of creating eager. Using lazy can be useful when you * only need to create beans if they are explicit in-use. + * + * NOTE: lazy does not support init or destroy methods. */ boolean lazy() default false; /** * The optional name of a method to call on the bean instance during initialization. * - * If the bean is an {@link Service} instance then Camel will automatically use start as init method, if none - * explicit configured. + * If no destroy method has been configured, then Camel will auto-detect as follows: If the bean is {@link Service} + * then start method is used. */ String initMethod() default ""; /** * The optional name of a method to call on the bean instance during destruction. * - * If the bean is an {@link Service} instance then Camel will automatically use stop as destroy method, if none - * explicit configured. + * If no destroy method has been configured, then Camel will auto-detect as follows: If the bean is {@link Service} + * then stop method is used. If the bean is {@link java.io.Closeable} then close method is used. */ String destroyMethod() default ""; } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java index 48b997d51a9..71f29090a8b 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java @@ -16,6 +16,7 @@ */ package org.apache.camel.impl.engine; +import java.io.Closeable; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -696,4 +697,26 @@ public class CamelPostProcessorHelper implements CamelContextAware { } return true; } + + /** + * Find the best init method to use for the given bean + */ + public static String initMethodCandidate(Object bean) { + if (bean instanceof Service) { + return "start"; + } + return null; + } + + /** + * Find the best destroy method to use for the given bean + */ + public static String destroyMethodCandidate(Object bean) { + if (bean instanceof Service) { + return "stop"; + } else if (bean instanceof Closeable) { + return "close"; + } + return null; + } } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java index 6781a0163c0..7fd5cdbf967 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java @@ -35,7 +35,6 @@ import org.apache.camel.EndpointInject; import org.apache.camel.Produce; import org.apache.camel.PropertyInject; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.Service; import org.apache.camel.spi.CamelBeanPostProcessor; import org.apache.camel.spi.CamelBeanPostProcessorInjector; import org.apache.camel.support.DefaultEndpoint; @@ -540,11 +539,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, Ca if (unbindEnabled) { getOrLookupCamelContext().getRegistry().unbind(name); } - if (isEmpty(initMethod) && bean instanceof Service) { - initMethod = "start"; + if (isEmpty(initMethod)) { + initMethod = CamelPostProcessorHelper.initMethodCandidate(bean); } - if (isEmpty(destroyMethod) && bean instanceof Service) { - destroyMethod = "stop"; + if (isEmpty(destroyMethod)) { + destroyMethod = CamelPostProcessorHelper.destroyMethodCandidate(bean); } // use dependency injection factory to perform the task of binding the bean to registry Runnable task = PluginHelper.getDependencyInjectionAnnotationFactory(getOrLookupCamelContext()) @@ -580,12 +579,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, Ca value = ReflectionHelper.getField(field, bean); } if (value != null) { - // automatic support Service for init/destroy methods - if (isEmpty(initMethod) && bean instanceof Service) { - initMethod = "start"; + if (isEmpty(initMethod)) { + initMethod = CamelPostProcessorHelper.initMethodCandidate(bean); } - if (isEmpty(destroyMethod) && bean instanceof Service) { - destroyMethod = "stop"; + if (isEmpty(destroyMethod)) { + destroyMethod = CamelPostProcessorHelper.destroyMethodCandidate(bean); } if (unbindEnabled) { getOrLookupCamelContext().getRegistry().unbind(name); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java index 658b5bae758..781de63fad0 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java @@ -16,6 +16,7 @@ */ package org.apache.camel.support.scan; +import java.io.Closeable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -118,7 +119,6 @@ public class PackageScanHelper { } Object bean = entry.getValue(); String beanName = c.getName(); - // special for init method as we need to defer calling it at a late phase String initMethod = ann.initMethod(); if (isEmpty(initMethod) && bean instanceof Service) { initMethod = "start"; @@ -126,9 +126,12 @@ public class PackageScanHelper { String destroyMethod = ann.destroyMethod(); if (isEmpty(destroyMethod) && bean instanceof Service) { destroyMethod = "stop"; + } else if (isEmpty(destroyMethod) && bean instanceof Closeable) { + destroyMethod = "close"; } // - bind to registry if @org.apache.camel.BindToRegistry is present // use dependency injection factory to perform the task of binding the bean to registry + // use null for init method as we need to defer calling it at a late phase Runnable task = PluginHelper.getDependencyInjectionAnnotationFactory(camelContext) .createBindToRegistryFactory(name, bean, c, beanName, false, null, destroyMethod); // defer calling init methods until dependency injection in phase-4 is complete
