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 2019/05/27 09:54:22 UTC

[camel] 01/02: CAMEL-13582: Camel Main - @BindToRegistry are processed earlier and for methods then process them in order where the most basic methods are executed first.

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

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

commit 703b3851ad39d6fddf7fe394e9afca965e427907
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon May 27 10:36:09 2019 +0200

    CAMEL-13582: Camel Main - @BindToRegistry are processed earlier and for methods then process them in order where the most basic methods are executed first.
---
 .../impl/engine/DefaultCamelBeanPostProcessor.java | 49 +++++++++++++++++++---
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index 0e7003b..cab3f8b 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -19,6 +19,9 @@ package org.apache.camel.impl.engine;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.camel.BeanInject;
@@ -81,6 +84,8 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
 
         injectClass(bean, beanName);
         injectNestedClasses(bean, beanName);
+        injectBindToRegistryFields(bean, beanName);
+        injectBindToRegistryMethods(bean, beanName);
         injectFields(bean, beanName);
         injectMethods(bean, beanName);
 
@@ -181,7 +186,13 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
                     String uri = produce.value().isEmpty() ? produce.uri() : produce.value();
                     injectField(field, uri, produce.property(), bean, beanName, produce.binding());
                 }
+            }
+        });
+    }
 
+    protected void injectBindToRegistryFields(final Object bean, final String beanName) {
+        ReflectionHelper.doWithFields(bean.getClass(), new ReflectionHelper.FieldCallback() {
+            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                 BindToRegistry bind = field.getAnnotation(BindToRegistry.class);
                 if (bind != null && getPostProcessorHelper().matchContext(bind.context())) {
                     bindToRegistry(field, bind.value(), bean, beanName);
@@ -222,6 +233,29 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
         });
     }
 
+    protected void injectBindToRegistryMethods(final Object bean, final String beanName) {
+        // sort the methods so the simplest are used first
+
+        final List<Method> methods = new ArrayList<Method>();
+        ReflectionHelper.doWithMethods(bean.getClass(), method -> {
+            BindToRegistry bind = method.getAnnotation(BindToRegistry.class);
+            if (bind != null && getPostProcessorHelper().matchContext(bind.context())) {
+                methods.add(method);
+            }
+        });
+
+        // sort methods on shortest number of parameters as we want to process the most simplest first
+        methods.sort(Comparator.comparingInt(Method::getParameterCount));
+
+        LOG.trace("Discovered {} @BindToRegistry methods", methods.size());
+
+        // bind each method
+        methods.forEach(method -> {
+            BindToRegistry bind = method.getAnnotation(BindToRegistry.class);
+            bindToRegistry(method, bind.value(), bean, beanName);
+        });
+    }
+
     protected void injectClass(final Object bean, final String beanName) {
         Class<?> clazz = bean.getClass();
         BindToRegistry ann = clazz.getAnnotation(BindToRegistry.class);
@@ -264,11 +298,6 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
             String uri = produce.value().isEmpty() ? produce.uri() : produce.value();
             setterInjection(method, bean, beanName, uri, produce.property());
         }
-
-        BindToRegistry bind = method.getAnnotation(BindToRegistry.class);
-        if (bind != null && getPostProcessorHelper().matchContext(bind.context())) {
-            bindToRegistry(method, bind.value(), bean, beanName);
-        }
     }
 
     public void setterInjection(Method method, Object bean, String beanName, String endpointUri, String endpointProperty) {
@@ -408,6 +437,16 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
                             parameters[i] = camelContext.getTypeConverter().convertTo(type, value);
                         }
                     }
+                } else {
+                    // okay attempt to default to singleton instances from the registry
+                    Set<?> instances = camelContext.getRegistry().findByType(type);
+                    if (instances.size() == 1) {
+                        parameters[i] = instances.iterator().next();
+                    } else {
+                        // there are multiple instances of the same type, so barf
+                        throw new IllegalArgumentException("Multiple beans of the same type: " + type
+                                + " exists in the Camel registry. Specify the bean name on @BeanInject to bind to a single bean, at the method: " + method);
+                    }
                 }
             }