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); + } } } }
