This is an automated email from the ASF dual-hosted git repository. ggrzybek 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 0be0a73e4f0 [CAMEL-19564] Delay registration of beans defined in *.java files 0be0a73e4f0 is described below commit 0be0a73e4f030eb11f060deea1e0027726c360e3 Author: Grzegorz Grzybek <gr.grzy...@gmail.com> AuthorDate: Fri Jun 30 11:31:22 2023 +0200 [CAMEL-19564] Delay registration of beans defined in *.java files --- .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 75 ++++++++++++++-------- 1 file changed, 49 insertions(+), 26 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 b7731c717ed..53faedd0d7c 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 @@ -67,9 +67,11 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { public static final String NAMESPACE = "http://camel.apache.org/schema/spring"; private static final List<String> NAMESPACES = List.of("", NAMESPACE); + private final Map<String, Boolean> preparseDone = new ConcurrentHashMap<>(); private final Map<String, Resource> resourceCache = new ConcurrentHashMap<>(); private final Map<String, XmlStreamInfo> xmlInfoCache = new ConcurrentHashMap<>(); private final Map<String, BeansDefinition> camelAppCache = new ConcurrentHashMap<>(); + private final List<RegistryBeanDefinition> delayedRegistrations = new ArrayList<>(); private final AtomicInteger counter = new AtomicInteger(0); @@ -85,6 +87,9 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { public void preParseRoute(Resource resource) throws Exception { // preparsing is done at early stage, so we have a chance to load additional beans and populate // Camel registry + if (preparseDone.getOrDefault(resource.getLocation(), false)) { + return; + } XmlStreamInfo xmlInfo = xmlInfo(resource); if (xmlInfo.isValid()) { String root = xmlInfo.getRootElementName(); @@ -97,6 +102,7 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { }); } } + preparseDone.put(resource.getLocation(), true); } @Override @@ -149,6 +155,7 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { resourceCache.remove(resourceLocation); xmlInfoCache.remove(resourceLocation); camelAppCache.remove(resourceLocation); + preparseDone.remove(resourceLocation); } @Override @@ -164,6 +171,14 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { } private void configureCamel(BeansDefinition app) { + if (!delayedRegistrations.isEmpty()) { + // some of the beans were not available yet, so we have to try register them now + for (RegistryBeanDefinition bean : delayedRegistrations) { + registerBeanDefinition(bean, false); + } + delayedRegistrations.clear(); + } + // we have access to beans and spring beans, but these are already processed // in preParseRoute() and possibly registered in // org.apache.camel.main.BaseMainSupport.postProcessCamelRegistry() (if given Main implementation @@ -232,13 +247,6 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { }; } - @Override - protected void doStop() throws Exception { - resourceCache.clear(); - xmlInfoCache.clear(); - camelAppCache.clear(); - } - private Resource resource(Resource resource) { return resourceCache.computeIfAbsent(resource.getLocation(), l -> new CachedResource(resource)); } @@ -289,25 +297,7 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { // <bean>s - register Camel beans directly with Camel injection for (RegistryBeanDefinition bean : app.getBeans()) { - String type = bean.getType(); - String name = bean.getName(); - if (name == null || "".equals(name.trim())) { - name = type; - } - if (type != null && !type.startsWith("#")) { - type = "#class:" + type; - try { - final Object target = PropertyBindingSupport.resolveBean(getCamelContext(), type); - - if (bean.getProperties() != null && !bean.getProperties().isEmpty()) { - PropertyBindingSupport.setPropertiesOnTarget(getCamelContext(), target, bean.getProperties()); - } - getCamelContext().getRegistry().unbind(name); - getCamelContext().getRegistry().bind(name, target); - } catch (Exception e) { - LOG.warn("Problem creating bean {}", type, e); - } - } + registerBeanDefinition(bean, true); } // <s:bean>, <s:beans> and <s:alias> elements - all the elements in single BeansDefinition have @@ -321,4 +311,37 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { } } + /** + * Try to instantiate bean from the definition. Depending on the stage ({@link #preParseRoute} or + * {@link #doLoadRouteBuilder}), a failure may lead to delayed registration. + * + * @param def + * @param delayIfFailed + */ + private void registerBeanDefinition(RegistryBeanDefinition def, boolean delayIfFailed) { + String type = def.getType(); + String name = def.getName(); + if (name == null || "".equals(name.trim())) { + name = type; + } + if (type != null && !type.startsWith("#")) { + type = "#class:" + type; + try { + final Object target = PropertyBindingSupport.resolveBean(getCamelContext(), type); + + if (def.getProperties() != null && !def.getProperties().isEmpty()) { + PropertyBindingSupport.setPropertiesOnTarget(getCamelContext(), target, def.getProperties()); + } + getCamelContext().getRegistry().unbind(name); + getCamelContext().getRegistry().bind(name, target); + } catch (Exception e) { + if (delayIfFailed) { + delayedRegistrations.add(def); + } else { + LOG.warn("Problem creating bean {}", type, e); + } + } + } + } + }