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

Reply via email to