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/23 12:45:12 UTC
[camel] 01/01: CAMEL-18189: component-scan for beans by class should be phased to ensure their inter dependency can be injected by Camel @BindToRegistry annotations.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch scan-bean-order
in repository https://gitbox.apache.org/repos/asf/camel.git
commit ec2b8f5ba899a60cc39ecc1499d2dd35b2428e10
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Jul 23 14:44:57 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.
---
.../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);
+ }
}
}
}