You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/07/24 07:29:19 UTC

[camel] branch main updated: CAMEL-18189: component-scan for beans by class should be phased to ensure their inter dependency can be injected by Camel @BindToRegistry annotations. (#10790)

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


The following commit(s) were added to refs/heads/main by this push:
     new a63173ea93f CAMEL-18189: component-scan for beans by class should be phased to ensure their inter dependency can be injected by Camel @BindToRegistry annotations. (#10790)
a63173ea93f is described below

commit a63173ea93f6340f2a4da187d9e71019e0ea1955
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Jul 24 09:29:12 2023 +0200

    CAMEL-18189: component-scan for beans by class should be phased to ensure their inter dependency can be injected by Camel @BindToRegistry annotations. (#10790)
---
 .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java   | 48 +++++++++++++++++++---
 1 file changed, 43 insertions(+), 5 deletions(-)

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 53faedd0d7c..f1b32b1d1d3 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
@@ -18,6 +18,7 @@ package org.apache.camel.dsl.xml.io;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -29,6 +30,7 @@ import org.w3c.dom.Document;
 
 import org.apache.camel.BindToRegistry;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.RouteConfigurationBuilder;
@@ -51,6 +53,7 @@ import org.apache.camel.spi.Registry;
 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.PropertyBindingSupport;
 import org.apache.camel.xml.in.ModelParser;
 import org.apache.camel.xml.io.util.XmlStreamDetector;
@@ -58,6 +61,8 @@ import org.apache.camel.xml.io.util.XmlStreamInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.camel.util.ObjectHelper.isEmpty;
+
 @ManagedResource(description = "Managed XML RoutesBuilderLoader")
 @RoutesLoader(XmlRoutesBuilderLoader.EXTENSION)
 public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport {
@@ -281,14 +286,47 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport {
                         = getCamelContext().getCamelContextExtension().getContextPlugin(PackageScanClassResolver.class);
                 Injector injector = getCamelContext().getInjector();
                 if (scanner != null && injector != null) {
+                    Map<Class<?>, Object> created = new HashMap<>();
                     for (String pkg : packagesToScan) {
                         Set<Class<?>> classes = scanner.findAnnotated(BindToRegistry.class, pkg);
                         for (Class<?> c : classes) {
-                            // should:
-                            // - call org.apache.camel.spi.CamelBeanPostProcessor.postProcessBeforeInitialization
-                            // - call org.apache.camel.spi.CamelBeanPostProcessor.postProcessAfterInitialization
-                            // - bind to registry if @org.apache.camel.BindToRegistry is present
-                            injector.newInstance(c, true);
+                            // phase-1: create empty bean instance without any bean post-processing
+                            Object b = injector.newInstance(c, false);
+                            if (b != null) {
+                                created.put(c, b);
+                            }
+                        }
+                        for (Class<?> c : created.keySet()) {
+                            // phase-2: discover any created beans has @BindToRegistry to register them eager
+                            BindToRegistry ann = c.getAnnotation(BindToRegistry.class);
+                            if (ann != null) {
+                                String name = ann.value();
+                                if (isEmpty(name)) {
+                                    name = c.getSimpleName();
+                                }
+                                Object bean = created.get(c);
+                                String beanName = c.getName();
+                                // - bind to registry if @org.apache.camel.BindToRegistry is present
+                                // use dependency injection factory to perform the task of binding the bean to registry
+                                Runnable task = PluginHelper.getDependencyInjectionAnnotationFactory(getCamelContext())
+                                        .createBindToRegistryFactory(name, bean, beanName, false);
+                                task.run();
+                            }
+                        }
+                        for (Class<?> c : created.keySet()) {
+                            // phase-3: now we can do bean post-processing on the created beans
+                            Object bean = created.get(c);
+                            String beanName = c.getName();
+                            try {
+                                // - call org.apache.camel.spi.CamelBeanPostProcessor.postProcessBeforeInitialization
+                                // - call org.apache.camel.spi.CamelBeanPostProcessor.postProcessAfterInitialization
+                                PluginHelper.getBeanPostProcessor(getCamelContext()).postProcessBeforeInitialization(bean,
+                                        beanName);
+                                PluginHelper.getBeanPostProcessor(getCamelContext()).postProcessAfterInitialization(bean,
+                                        beanName);
+                            } catch (Exception e) {
+                                throw new RuntimeCamelException("Error post-processing bean: " + beanName, e);
+                            }
                         }
                     }
                 }