This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch lazy
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 45fece2bb314e97dfd7250c52507b862e03620a4
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Aug 29 09:13:15 2024 +0200

    CAMEL-21137: camel-core - Add lazy option to @BindToRegistry
---
 .../dsl/java/joor/JavaRoutesBuilderLoader.java     |  4 +-
 .../injection/AnnotationDependencyInjection.java   | 69 ++++++++++++++--------
 2 files changed, 48 insertions(+), 25 deletions(-)

diff --git 
a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
 
b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
index 317693f93bd..d805e559cd7 100644
--- 
a/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
+++ 
b/dsl/camel-java-joor-dsl/src/main/java/org/apache/camel/dsl/java/joor/JavaRoutesBuilderLoader.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.camel.BindToRegistry;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.RoutesBuilder;
@@ -138,8 +139,9 @@ public class JavaRoutesBuilderLoader extends 
ExtendedRouteBuilderLoaderSupport {
 
             Class<?> clazz = result.getClass(className);
             if (clazz != null) {
+                BindToRegistry bir = clazz.getAnnotation(BindToRegistry.class);
                 boolean skip = clazz.isInterface() || 
Modifier.isAbstract(clazz.getModifiers())
-                        || Modifier.isPrivate(clazz.getModifiers());
+                        || Modifier.isPrivate(clazz.getModifiers()) || (bir != 
null && bir.lazy());
                 // must have a default no-arg constructor to be able to create 
an instance
                 boolean ctr = ObjectHelper.hasDefaultNoArgConstructor(clazz);
                 if (ctr && !skip) {
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
index 1d9ef7ace70..e042e6ecaa3 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
@@ -20,6 +20,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Supplier;
 
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.enterprise.inject.Produces;
@@ -136,31 +137,51 @@ public final class AnnotationDependencyInjection {
         @Override
         public void postCompile(CamelContext camelContext, String name, 
Class<?> clazz, byte[] byteCode, Object instance)
                 throws Exception {
-            if (instance == null) {
-                return;
-            }
 
-            BindToRegistry bir = 
instance.getClass().getAnnotation(BindToRegistry.class);
-            Configuration cfg = 
instance.getClass().getAnnotation(Configuration.class);
-            if (bir != null || cfg != null || instance instanceof 
CamelConfiguration) {
-                CamelBeanPostProcessor bpp = 
PluginHelper.getBeanPostProcessor(camelContext);
-                if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
-                    name = bir.value();
-                } else if (cfg != null && 
ObjectHelper.isNotEmpty(cfg.value())) {
-                    name = cfg.value();
-                }
-                // to support hot reloading of beans then we need to enable 
unbind mode in bean post processor
-                bpp.setUnbindEnabled(true);
-                try {
-                    // this class uses camels own annotations so the bind to 
registry happens
-                    // automatic by the bean post processor
-                    bpp.postProcessBeforeInitialization(instance, name);
-                    bpp.postProcessAfterInitialization(instance, name);
-                } finally {
-                    bpp.setUnbindEnabled(false);
-                }
-                if (instance instanceof CamelConfiguration) {
-                    ((CamelConfiguration) instance).configure(camelContext);
+            BindToRegistry bir = clazz.getAnnotation(BindToRegistry.class);
+            Configuration cfg = clazz.getAnnotation(Configuration.class);
+
+            // special for lazy beans which we must create on-demand
+            if (instance == null && bir != null && bir.lazy()) {
+                final String beanName = bir.value();
+                instance = (Supplier<Object>) () -> {
+                    Object answer = 
camelContext.getInjector().newInstance(clazz);
+                    CamelBeanPostProcessor bpp = 
PluginHelper.getBeanPostProcessor(camelContext);
+                    try {
+                        bpp.postProcessBeforeInitialization(answer, beanName);
+                        bpp.postProcessAfterInitialization(answer, beanName);
+                    } catch (Exception e) {
+                        throw RuntimeCamelException.wrapRuntimeException(e);
+                    }
+                    return answer;
+                };
+                // unbind old bean and register lazy bean
+                camelContext.getRegistry().unbind(beanName);
+                // use dependency injection factory to perform the task of 
binding the bean to registry
+                Runnable task = 
PluginHelper.getDependencyInjectionAnnotationFactory(camelContext)
+                        .createBindToRegistryFactory(name, instance, clazz, 
beanName, false);
+                task.run();
+            } else {
+                if (bir != null || cfg != null || instance instanceof 
CamelConfiguration) {
+                    CamelBeanPostProcessor bpp = 
PluginHelper.getBeanPostProcessor(camelContext);
+                    if (bir != null && ObjectHelper.isNotEmpty(bir.value())) {
+                        name = bir.value();
+                    } else if (cfg != null && 
ObjectHelper.isNotEmpty(cfg.value())) {
+                        name = cfg.value();
+                    }
+                    // to support hot reloading of beans then we need to 
enable unbind mode in bean post processor
+                    bpp.setUnbindEnabled(true);
+                    try {
+                        // this class uses camels own annotations so the bind 
to registry happens
+                        // automatic by the bean post processor
+                        bpp.postProcessBeforeInitialization(instance, name);
+                        bpp.postProcessAfterInitialization(instance, name);
+                    } finally {
+                        bpp.setUnbindEnabled(false);
+                    }
+                    if (instance instanceof CamelConfiguration) {
+                        ((CamelConfiguration) 
instance).configure(camelContext);
+                    }
                 }
             }
         }

Reply via email to