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

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


The following commit(s) were added to refs/heads/camel-4.10.x by this push:
     new eb472155f4c CAMEL-21794: camel-jbang - Export bean with lazy-bean 
should not initialize the bean if not needed (#17264)
eb472155f4c is described below

commit eb472155f4c6a4b835d0352a22b095739cbde6a4
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Feb 25 14:54:59 2025 +0000

    CAMEL-21794: camel-jbang - Export bean with lazy-bean should not initialize 
the bean if not needed (#17264)
    
    * CAMEL-21794: camel-jbang - Export bean with lazy-bean should not 
initialize the bean if not needed
---
 .../camel/component/consul/ConsulRegistry.java     |  6 ++
 .../main/java/org/apache/camel/spi/Registry.java   | 28 ++++++-
 ...efaultDependencyInjectionAnnotationFactory.java | 12 ++-
 ...oRegistrySupplierBeanInitDestroyMethodTest.java | 91 ++++++++++++++++++++++
 .../org/apache/camel/support/DefaultRegistry.java  | 38 +++++++--
 .../org/apache/camel/support/SimpleRegistry.java   |  6 ++
 .../dsl/jbang/core/commands/ExportBaseCommand.java |  4 +-
 .../camel/dsl/jbang/core/commands/ExportTest.java  |  2 +-
 .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java   | 44 ++++++++++-
 .../dsl/yaml/deserializers/BeansDeserializer.java  | 44 ++++++++++-
 10 files changed, 258 insertions(+), 17 deletions(-)

diff --git 
a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
 
b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
index 27c8231fd14..ee3e36b090e 100644
--- 
a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
+++ 
b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulRegistry.java
@@ -171,6 +171,12 @@ public class ConsulRegistry implements Registry {
         throw new UnsupportedOperationException("Binding with supplier not 
supported");
     }
 
+    @Override
+    public void bind(String id, Class<?> type, Supplier<Object> bean, String 
initMethod, String destroyMethod)
+            throws RuntimeCamelException {
+        throw new UnsupportedOperationException("Binding with supplier not 
supported");
+    }
+
     @Override
     public void bindAsPrototype(String id, Class<?> type, Supplier<Object> 
bean) throws RuntimeCamelException {
         throw new UnsupportedOperationException("Binding with supplier not 
supported");
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java
index be0d24b4e7e..48601f45ade 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Registry.java
@@ -29,7 +29,7 @@ public interface Registry extends BeanRepository {
     /**
      * Binds the bean to the repository (if possible).
      *
-     * If the bean is {@link CamelContextAware} then the registry will 
automatic inject the context if possible.
+     * If the bean is {@link CamelContextAware} then the registry will 
automatically inject the context if possible.
      *
      * @param  id                    the id of the bean
      * @param  bean                  the bean
@@ -44,7 +44,7 @@ public interface Registry extends BeanRepository {
     /**
      * Binds the bean to the repository (if possible).
      *
-     * If the bean is {@link CamelContextAware} then the registry will 
automatic inject the context if possible.
+     * If the bean is {@link CamelContextAware} then the registry will 
automatically inject the context if possible.
      *
      * @param  id                    the id of the bean
      * @param  bean                  the bean
@@ -63,7 +63,7 @@ public interface Registry extends BeanRepository {
      * <p/>
      * Binding by id and type allows to bind multiple entries with the same id 
but with different type.
      *
-     * If the bean is {@link CamelContextAware} then the registry will 
automatic inject the context if possible.
+     * If the bean is {@link CamelContextAware} then the registry will 
automatically inject the context if possible.
      *
      * @param  id                    the id of the bean
      * @param  type                  the type of the bean to associate the 
binding
@@ -77,7 +77,7 @@ public interface Registry extends BeanRepository {
      * <p/>
      * Binding by id and type allows to bind multiple entries with the same id 
but with different type.
      *
-     * If the bean is {@link CamelContextAware} then the registry will 
automatic inject the context if possible.
+     * If the bean is {@link CamelContextAware} then the registry will 
automatically inject the context if possible.
      *
      * @param  id                    the id of the bean
      * @param  type                  the type of the bean to associate the 
binding
@@ -103,6 +103,26 @@ public interface Registry extends BeanRepository {
      */
     void bind(String id, Class<?> type, Supplier<Object> bean) throws 
RuntimeCamelException;
 
+    /**
+     * Binds the bean to the repository (if possible).
+     * <p/>
+     * Camel will cache the result from the supplier from first lookup 
(singleton scope). If you do not need cached then
+     * use {@link #bindAsPrototype(String, Class, Supplier)} instead.
+     * <p/>
+     * Binding by id and type allows to bind multiple entries with the same id 
but with different type.
+     *
+     * If the bean is {@link CamelContextAware} then the registry will 
automatically inject the context if possible.
+     *
+     * @param  id                    the id of the bean
+     * @param  type                  the type of the bean to associate the 
binding
+     * @param  bean                  a supplier for the bean
+     * @param  initMethod            optional init method (invoked at bind)
+     * @param  destroyMethod         optional destroy method (invoked at 
unbind or stopping Camel)
+     * @throws RuntimeCamelException is thrown if binding is not possible
+     */
+    void bind(String id, Class<?> type, Supplier<Object> bean, String 
initMethod, String destroyMethod)
+            throws RuntimeCamelException;
+
     /**
      * Binds the bean (via a supplier) to the repository (if possible).
      * <p/>
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
index b665e0209fe..c7010906870 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
@@ -52,6 +52,12 @@ public class DefaultDependencyInjectionAnnotationFactory
     public Runnable createBindToRegistryFactory(
             String id, Object bean, Class<?> beanType, String beanName, 
boolean beanPostProcess,
             String initMethod, String destroyMethod) {
+
+        if (beanType.isAssignableFrom(Supplier.class)) {
+            beanType = Object.class;
+        }
+        final Class<?> beanTarget = beanType;
+
         return () -> {
             if (beanPostProcess) {
                 try {
@@ -66,7 +72,11 @@ public class DefaultDependencyInjectionAnnotationFactory
             if (bean instanceof Supplier) {
                 // must be Supplier<Object> to ensure correct binding
                 Supplier<Object> sup = (Supplier<Object>) bean;
-                camelContext.getRegistry().bind(id, beanType, sup);
+                if (initMethod != null || destroyMethod != null) {
+                    camelContext.getRegistry().bind(id, beanTarget, sup, 
initMethod, destroyMethod);
+                } else {
+                    camelContext.getRegistry().bind(id, beanTarget, sup);
+                }
             } else {
                 if (initMethod != null || destroyMethod != null) {
                     camelContext.getRegistry().bind(id, bean, initMethod, 
destroyMethod);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistrySupplierBeanInitDestroyMethodTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistrySupplierBeanInitDestroyMethodTest.java
new file mode 100644
index 00000000000..218a19b3e12
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistrySupplierBeanInitDestroyMethodTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl;
+
+import java.util.function.Supplier;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.spi.CamelBeanPostProcessor;
+import org.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class BindToRegistrySupplierBeanInitDestroyMethodTest extends 
ContextTestSupport {
+
+    @BindToRegistry(initMethod = "start", destroyMethod = "stop")
+    public Supplier<FooService> myFoo() {
+        return () -> new FooService("World");
+    }
+
+    @Test
+    public void testStop() throws Exception {
+        // bean post processing dont run on ContextTestSupport
+        CamelBeanPostProcessor cbpp = 
PluginHelper.getBeanPostProcessor(context);
+        cbpp.postProcessBeforeInitialization(this, "this");
+        cbpp.postProcessAfterInitialization(this, "this");
+
+        FooService foo = context.getRegistry().lookupByNameAndType("myFoo", 
FooService.class);
+        assertNotNull(foo);
+        assertEquals("Started World", foo.getMessage());
+
+        // stop camel should trigger destroy
+        context.stop();
+
+        assertEquals("Stopped", foo.getMessage());
+    }
+
+    @Test
+    public void testUnbind() throws Exception {
+        // bean post processing dont run on ContextTestSupport
+        CamelBeanPostProcessor cbpp = 
PluginHelper.getBeanPostProcessor(context);
+        cbpp.postProcessBeforeInitialization(this, "this");
+        cbpp.postProcessAfterInitialization(this, "this");
+
+        FooService foo = context.getRegistry().lookupByNameAndType("myFoo", 
FooService.class);
+        assertNotNull(foo);
+        assertEquals("Started World", foo.getMessage());
+
+        // unbind should trigger destroy
+        context.getRegistry().unbind("myFoo");
+        assertEquals("Stopped", foo.getMessage());
+    }
+
+    public static class FooService {
+
+        private String message;
+
+        public FooService(String message) {
+            this.message = message;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public void start() {
+            this.message = "Started " + message;
+        }
+
+        public void stop() {
+            this.message = "Stopped";
+        }
+
+    }
+}
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
index 182c53e6808..2e4c753ddef 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
@@ -214,6 +214,29 @@ public class DefaultRegistry extends ServiceSupport 
implements Registry, LocalBe
         }
     }
 
+    @Override
+    public void bind(String id, Class<?> type, Supplier<Object> bean, String 
initMethod, String destroyMethod)
+            throws RuntimeCamelException {
+        if (bean != null) {
+            // wrap in cached supplier (memorize)
+            Supplier<Object> sup = Suppliers.memorize(() -> {
+                Object answer = bean.get();
+                if (isNotEmpty(initMethod)) {
+                    try {
+                        ObjectHelper.invokeMethodSafe(initMethod, answer);
+                    } catch (Exception e) {
+                        throw 
RuntimeCamelException.wrapRuntimeCamelException(e);
+                    }
+                }
+                return answer;
+            });
+            supplierRegistry.bind(id, type, sup);
+            if (isNotEmpty(destroyMethod)) {
+                beansToDestroy.put(id, new KeyValueHolder<>(sup, 
destroyMethod));
+            }
+        }
+    }
+
     @Override
     public void bindAsPrototype(String id, Class<?> type, Supplier<Object> 
bean) throws RuntimeCamelException {
         if (bean != null) {
@@ -234,11 +257,16 @@ public class DefaultRegistry extends ServiceSupport 
implements Registry, LocalBe
         if (holder != null) {
             String destroyMethod = holder.getValue();
             Object target = holder.getKey();
-            try {
-                
org.apache.camel.support.ObjectHelper.invokeMethodSafe(destroyMethod, target);
-            } catch (Exception e) {
-                LOG.warn("Error invoking destroy method: {} on bean: {} due 
to: {}. This exception is ignored.",
-                        destroyMethod, target, e.getMessage(), e);
+            if (target instanceof Supplier sup) {
+                target = sup.get();
+            }
+            if (target != null) {
+                try {
+                    
org.apache.camel.support.ObjectHelper.invokeMethodSafe(destroyMethod, target);
+                } catch (Exception e) {
+                    LOG.warn("Error invoking destroy method: {} on bean: {} 
due to: {}. This exception is ignored.",
+                            destroyMethod, target, e.getMessage(), e);
+                }
             }
         }
     }
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/SimpleRegistry.java 
b/core/camel-support/src/main/java/org/apache/camel/support/SimpleRegistry.java
index 0018f9937a5..388f4222d91 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/SimpleRegistry.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/SimpleRegistry.java
@@ -118,6 +118,12 @@ public class SimpleRegistry extends LinkedHashMap<String, 
Map<Class<?>, Object>>
         throw new UnsupportedOperationException("Use SupplierRegistry");
     }
 
+    @Override
+    public void bind(String id, Class<?> type, Supplier<Object> bean, String 
initMethod, String destroyMethod)
+            throws RuntimeCamelException {
+        throw new UnsupportedOperationException("Use SupplierRegistry");
+    }
+
     @Override
     public void bindAsPrototype(String id, Class<?> type, Supplier<Object> 
bean) {
         throw new UnsupportedOperationException("Use SupplierRegistry");
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
index 2f019aae06e..aca19671dd0 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
@@ -237,9 +237,9 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
                         description = "Whether to ignore route loading and 
compilation errors (use this with care!)")
     protected boolean ignoreLoadingError;
 
-    @CommandLine.Option(names = { "--lazy-bean" },
+    @CommandLine.Option(names = { "--lazy-bean" }, defaultValue = "true",
                         description = "Whether to use lazy bean initialization 
(can help with complex classloading issues")
-    protected boolean lazyBean;
+    protected boolean lazyBean = true;
 
     protected boolean symbolicLink;     // copy source files using symbolic 
link
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
index 26a9807e750..6565b115b9d 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
@@ -166,7 +166,7 @@ class ExportTest {
     @MethodSource("runtimeProvider")
     public void shouldExportLazyBean(RuntimeType rt) throws Exception {
         Export command = createCommand(rt, new String[] { 
"classpath:route.yaml", "file:src/test/resources/LazyFoo.java" },
-                "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet", "--lazy-bean");
+                "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet", "--lazy-bean=true");
         int exit = command.doCall();
 
         Assertions.assertEquals(0, exit);
diff --git 
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
 
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
index 534575475fe..9f1448e725d 100644
--- 
a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
+++ 
b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
@@ -24,6 +24,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 import org.w3c.dom.Document;
 
@@ -48,9 +50,11 @@ import 
org.apache.camel.model.dataformat.DataFormatsDefinition;
 import org.apache.camel.model.rest.RestConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.annotations.RoutesLoader;
 import org.apache.camel.support.CachedResource;
+import org.apache.camel.support.PluginHelper;
 import org.apache.camel.support.scan.PackageScanHelper;
 import org.apache.camel.xml.io.util.XmlStreamDetector;
 import org.apache.camel.xml.io.util.XmlStreamInfo;
@@ -391,11 +395,25 @@ public class XmlRoutesBuilderLoader extends 
RouteBuilderLoaderSupport {
      * {@link #doLoadRouteBuilder}), a failure may lead to delayed 
registration.
      */
     private void registerBeanDefinition(BeanFactoryDefinition<?> def, boolean 
delayIfFailed) {
+        CamelBeanPostProcessor cbpp = 
PluginHelper.getBeanPostProcessor(getCamelContext());
+        Predicate<?> lazy = cbpp.getLazyBeanStrategy();
+
         String name = def.getName();
         String type = def.getType();
         try {
-            Object target = BeanModelHelper.newInstance(def, 
getCamelContext());
-            bindBean(def, name, target);
+            // only do lazy bean on 2nd pass as 1st pass may work
+            if (!delayIfFailed && lazy != null && lazy.test(null)) {
+                bindLazyBean(def, name, () -> {
+                    try {
+                        return BeanModelHelper.newInstance(def, 
getCamelContext());
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+            } else {
+                Object target = BeanModelHelper.newInstance(def, 
getCamelContext());
+                bindBean(def, name, target);
+            }
         } catch (Exception e) {
             if (delayIfFailed) {
                 delayedRegistrations.add(def);
@@ -417,4 +435,26 @@ public class XmlRoutesBuilderLoader extends 
RouteBuilderLoaderSupport {
         model.addCustomBean(def);
     }
 
+    protected void bindLazyBean(
+            BeanFactoryDefinition<?> def,
+            String name, Supplier<Object> target)
+            throws Exception {
+
+        Class<?> beanType = null;
+        if (def.getType() != null) {
+            beanType = 
getCamelContext().getClassResolver().resolveClass(def.getType());
+        }
+        if (beanType == null) {
+            beanType = Object.class;
+        }
+
+        // unbind in case we reload
+        getCamelContext().getRegistry().unbind(name);
+        getCamelContext().getRegistry().bind(name, beanType, target, 
def.getInitMethod(), def.getDestroyMethod());
+
+        // register bean in model
+        Model model = 
getCamelContext().getCamelContextExtension().getContextPlugin(Model.class);
+        model.addCustomBean(def);
+    }
+
 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
index aebec90986f..a5a53eded9d 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
@@ -20,6 +20,8 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
@@ -28,10 +30,12 @@ import 
org.apache.camel.dsl.yaml.common.YamlDeserializerSupport;
 import org.apache.camel.model.BeanFactoryDefinition;
 import org.apache.camel.model.BeanModelHelper;
 import org.apache.camel.model.Model;
+import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.CamelContextCustomizer;
 import org.apache.camel.spi.annotations.YamlIn;
 import org.apache.camel.spi.annotations.YamlProperty;
 import org.apache.camel.spi.annotations.YamlType;
+import org.apache.camel.support.PluginHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.snakeyaml.engine.v2.api.ConstructNode;
 import org.snakeyaml.engine.v2.nodes.Node;
@@ -96,11 +100,25 @@ public class BeansDeserializer extends 
YamlDeserializerSupport implements Constr
             List<BeanFactoryDefinition<?>> delayedRegistrations,
             BeanFactoryDefinition<?> def, boolean delayIfFailed) {
 
+        CamelBeanPostProcessor cbpp = 
PluginHelper.getBeanPostProcessor(camelContext);
+        Predicate<?> lazy = cbpp.getLazyBeanStrategy();
+
         String name = def.getName();
         String type = def.getType();
         try {
-            Object target = BeanModelHelper.newInstance(def, camelContext);
-            bindBean(camelContext, def, name, target);
+            // only do lazy bean on 2nd pass as 1st pass may work
+            if (!delayIfFailed && lazy != null && lazy.test(null)) {
+                bindLazyBean(camelContext, def, name, () -> {
+                    try {
+                        return BeanModelHelper.newInstance(def, camelContext);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                });
+            } else {
+                Object target = BeanModelHelper.newInstance(def, camelContext);
+                bindBean(camelContext, def, name, target);
+            }
         } catch (Exception e) {
             if (delayIfFailed) {
                 delayedRegistrations.add(def);
@@ -150,4 +168,26 @@ public class BeansDeserializer extends 
YamlDeserializerSupport implements Constr
         model.addCustomBean(def);
     }
 
+    protected void bindLazyBean(
+            CamelContext camelContext, BeanFactoryDefinition<?> def,
+            String name, Supplier<Object> target)
+            throws Exception {
+
+        Class<?> beanType = null;
+        if (def.getType() != null) {
+            beanType = 
camelContext.getClassResolver().resolveClass(def.getType());
+        }
+        if (beanType == null) {
+            beanType = Object.class;
+        }
+
+        // unbind in case we reload
+        camelContext.getRegistry().unbind(name);
+        camelContext.getRegistry().bind(name, beanType, target, 
def.getInitMethod(), def.getDestroyMethod());
+
+        // register bean in model
+        Model model = 
camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+        model.addCustomBean(def);
+    }
+
 }

Reply via email to