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/10/25 21:14:47 UTC

[camel] 01/01: CAMEL-20048: findSingleByType should be consistent. Added mandatory variant and NoSuchBeanTypeException that better reflect this.

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

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

commit f69417759f19e80c582a6d4063d97e8346526131
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 25 23:13:22 2023 +0200

    CAMEL-20048: findSingleByType should be consistent. Added mandatory variant and NoSuchBeanTypeException that better reflect this.
---
 .../apache/camel/component/saga/SagaProducer.java  |  5 +-
 .../JavaDslTransactedNoTXManagerTest.java          |  4 +-
 .../java/org/apache/camel/NoSuchBeanException.java |  7 ++
 .../org/apache/camel/NoSuchBeanTypeException.java  | 32 ++++++++
 .../java/org/apache/camel/spi/BeanRepository.java  | 18 +++++
 .../impl/engine/CamelPostProcessorHelper.java      | 18 ++---
 .../camel/impl/engine/SimpleCamelContext.java      |  5 +-
 .../java/org/apache/camel/impl/DefaultModel.java   | 15 +---
 .../camel/reifier/AbstractPolicyReifier.java       | 86 +++++++++-------------
 .../java/org/apache/camel/reifier/LogReifier.java  | 15 +---
 .../java/org/apache/camel/reifier/SagaReifier.java |  8 +-
 .../org/apache/camel/util/EndpointHelperTest.java  |  2 +-
 .../apache/camel/support/CamelContextHelper.java   |  8 ++
 .../org/apache/camel/support/DefaultEndpoint.java  |  5 +-
 .../org/apache/camel/support/EndpointHelper.java   |  9 +--
 .../camel/support/LifecycleStrategySupport.java    |  6 +-
 .../camel/support/PropertyBindingSupport.java      | 25 +------
 17 files changed, 121 insertions(+), 147 deletions(-)

diff --git a/components/camel-saga/src/main/java/org/apache/camel/component/saga/SagaProducer.java b/components/camel-saga/src/main/java/org/apache/camel/component/saga/SagaProducer.java
index d03ef49ee5d..31ee7fc9515 100644
--- a/components/camel-saga/src/main/java/org/apache/camel/component/saga/SagaProducer.java
+++ b/components/camel-saga/src/main/java/org/apache/camel/component/saga/SagaProducer.java
@@ -37,10 +37,7 @@ public class SagaProducer extends DefaultAsyncProducer {
 
         CamelSagaService sagaService = endpoint.getCamelContext().hasService(CamelSagaService.class);
         if (sagaService == null) {
-            sagaService = CamelContextHelper.findSingleByType(endpoint.getCamelContext(), CamelSagaService.class);
-        }
-        if (sagaService == null) {
-            throw new IllegalStateException("Cannot find saga service: saga producers can only be used within a saga");
+            sagaService = CamelContextHelper.mandatoryFindSingleByType(endpoint.getCamelContext(), CamelSagaService.class);
         }
         this.camelSagaService = sagaService;
     }
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/JavaDslTransactedNoTXManagerTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/JavaDslTransactedNoTXManagerTest.java
index 6d44c15c849..e0f9537f52c 100644
--- a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/JavaDslTransactedNoTXManagerTest.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/JavaDslTransactedNoTXManagerTest.java
@@ -44,7 +44,9 @@ public class JavaDslTransactedNoTXManagerTest extends ContextTestSupport {
             fail("Should have thrown an exception");
         } catch (Exception e) {
             NoSuchBeanException cause = assertIsInstanceOf(NoSuchBeanException.class, e.getCause());
-            assertEquals("No bean could be found in the registry of type: PlatformTransactionManager", cause.getMessage());
+            assertEquals(
+                    "No bean could be found in the registry for: org.springframework.transaction.PlatformTransactionManager",
+                    cause.getMessage());
         }
     }
 
diff --git a/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanException.java b/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanException.java
index 888668f1bcc..42bc3053d8d 100644
--- a/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanException.java
+++ b/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanException.java
@@ -28,6 +28,13 @@ public class NoSuchBeanException extends RuntimeCamelException {
         this.name = name;
     }
 
+    public NoSuchBeanException(String name, int size) {
+        super(size > 0
+                ? "Found " + size + " beans for: " + name + " in the registry, only 1 bean excepted."
+                : "No bean could be found in the registry for: " + name);
+        this.name = name;
+    }
+
     public NoSuchBeanException(String name, String type) {
         super("No bean could be found in the registry" + (name != null ? " for: " + name : "") + " of type: " + type);
         this.name = name;
diff --git a/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanTypeException.java b/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanTypeException.java
new file mode 100644
index 00000000000..cc791e98212
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/NoSuchBeanTypeException.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * A runtime exception if a given bean type could not be found in the {@link org.apache.camel.spi.Registry}
+ */
+public class NoSuchBeanTypeException extends NoSuchBeanException {
+
+    public NoSuchBeanTypeException(Class<?> type) {
+        super(type.getName());
+    }
+
+    public NoSuchBeanTypeException(Class<?> type, int size) {
+        super(type.getName(), size);
+    }
+
+}
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java b/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
index 4f7e2ff32f7..fb875d2812f 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
@@ -19,6 +19,8 @@ package org.apache.camel.spi;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.camel.NoSuchBeanTypeException;
+
 /**
  * Represents a bean repository used to lookup components by name and type. This allows Camel to plugin to third-party
  * bean repositories such as Spring, JNDI, OSGi.
@@ -78,6 +80,22 @@ public interface BeanRepository {
         }
     }
 
+    /**
+     * Finds the bean by type, if there is exactly only one instance of the bean
+     *
+     * @param  type the type of the beans
+     * @return      the single bean instance, or throws {@link NoSuchBeanTypeException} if not exactly one bean was
+     *              found.
+     */
+    default <T> T mandatoryFindSingleByType(Class<T> type) {
+        Set<T> set = findByType(type);
+        if (set.size() == 1) {
+            return set.iterator().next();
+        } else {
+            throw new NoSuchBeanTypeException(type, set.size());
+        }
+    }
+
     /**
      * Strategy to wrap the value to be stored in the registry.
      *
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
index 18ac9934660..cfdfa6f5729 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelPostProcessorHelper.java
@@ -308,8 +308,8 @@ public class CamelPostProcessorHelper implements CamelContextAware {
             if (getCamelContext() != null && type.isAssignableFrom(getCamelContext().getClass())) {
                 return getCamelContext();
             }
-            Set<?> found = getCamelContext() != null ? getCamelContext().getRegistry().findByType(type) : null;
-            if (found == null || found.isEmpty()) {
+            Object found = getCamelContext() != null ? getCamelContext().getRegistry().findSingleByType(type) : null;
+            if (found == null) {
                 // this may be a common type so lets check this first
                 if (getCamelContext() != null && type.isAssignableFrom(Registry.class)) {
                     return getCamelContext().getRegistry();
@@ -338,12 +338,8 @@ public class CamelPostProcessorHelper implements CamelContextAware {
                     return answer;
                 }
                 throw new NoSuchBeanException(null, type.getName());
-            } else if (found.size() > 1) {
-                throw new NoSuchBeanException(
-                        "Found " + found.size() + " beans of type: " + type + ". Only one bean expected.");
             } else {
-                // we found only one
-                return found.iterator().next();
+                return found;
             }
         } else {
             return CamelContextHelper.mandatoryLookup(getCamelContext(), name, type);
@@ -367,12 +363,8 @@ public class CamelPostProcessorHelper implements CamelContextAware {
         // create an instance of type
         Object bean = null;
         if (map == null) {
-            Set<?> instances = ecc.getRegistry().findByType(type);
-            if (instances.size() == 1) {
-                bean = instances.iterator().next();
-            } else if (instances.size() > 1) {
-                return null;
-            } else {
+            bean = ecc.getRegistry().findSingleByType(type);
+            if (bean == null) {
                 // attempt to create a new instance
                 try {
                     bean = ecc.getInjector().newInstance(type);
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 49ca74f5a37..04bc7c475f0 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -619,10 +619,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
         Tracer tracer = null;
         if (getRegistry() != null) {
             // lookup in registry
-            Map<String, Tracer> map = getRegistry().findByTypeWithName(Tracer.class);
-            if (map.size() == 1) {
-                tracer = map.values().iterator().next();
-            }
+            tracer = getRegistry().findSingleByType(Tracer.class);
         }
         if (tracer == null) {
             tracer = getCamelContextExtension().getContextPlugin(Tracer.class);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index 1ab011334be..e49e4f95459 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -22,7 +22,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.StringJoiner;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
@@ -31,7 +30,6 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.FailedToCreateRouteFromTemplateException;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.RouteTemplateContext;
 import org.apache.camel.model.BeanFactoryDefinition;
 import org.apache.camel.model.DataFormatDefinition;
@@ -701,16 +699,9 @@ public class DefaultModel implements Model {
         } else if (beanFactory.getType() != null && beanFactory.getType().startsWith("#type:")) {
             final CamelContext camelContext = routeTemplateContext.getCamelContext();
             Class<?> clazz = camelContext.getClassResolver().resolveMandatoryClass(beanFactory.getType().substring(6));
-            Set<?> found = camelContext.getRegistry().findByType(clazz);
-            if (found == null || found.isEmpty()) {
-                throw new NoSuchBeanException(null, clazz.getName());
-            } else if (found.size() > 1) {
-                throw new NoSuchBeanException(
-                        "Found " + found.size() + " beans of type: " + clazz + ". Only one bean expected.");
-            } else {
-                // do not set properties when using #type as it uses an existing shared bean
-                routeTemplateContext.bind(beanFactory.getName(), clazz, found.iterator().next());
-            }
+            Object found = camelContext.getRegistry().mandatoryFindSingleByType(clazz);
+            // do not set properties when using #type as it uses an existing shared bean
+            routeTemplateContext.bind(beanFactory.getName(), clazz, found);
         } else {
             // invalid syntax for the local bean, so lets report an exception
             throw new IllegalArgumentException(
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractPolicyReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractPolicyReifier.java
index 1850949ab06..912e0c84d01 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractPolicyReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractPolicyReifier.java
@@ -17,10 +17,8 @@
 package org.apache.camel.reifier;
 
 import java.lang.reflect.Method;
-import java.util.Map;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.ProcessorDefinition;
@@ -58,15 +56,10 @@ public abstract class AbstractPolicyReifier<T extends ProcessorDefinition<?>> ex
         // try to lookup by scoped type
         Policy answer = null;
         if (type != null) {
-            // try find by type, note that this method is not supported by all
-            // registry
-            Map<String, ?> types = findByTypeWithName(type);
-            if (types.size() == 1) {
-                // only one policy defined so use it
-                Object found = types.values().iterator().next();
-                if (type.isInstance(found)) {
-                    return type.cast(found);
-                }
+            // try find by type, note that this method is not supported by all registry
+            Policy found = findSingleByType(type);
+            if (found != null) {
+                return found;
             }
         }
 
@@ -85,51 +78,40 @@ public abstract class AbstractPolicyReifier<T extends ProcessorDefinition<?>> ex
             if (tmClazz != null) {
                 // see if we can find the platform transaction manager in the
                 // registry
-                Map<String, ?> maps = findByTypeWithName(tmClazz);
-                if (maps.size() == 1) {
-                    // only one platform manager then use it as default and
-                    // create a transacted
-                    // policy with it and default to required
+                Object transactionManager = mandatoryFindSingleByType(tmClazz);
+                // only one platform manager then use it as default and
+                // create a transacted
+                // policy with it and default to required
 
-                    // as we do not want dependency on spring jars in the
-                    // camel-core we use
-                    // reflection to lookup classes and create new objects and
-                    // call methods
-                    // as this is only done during route building it does not
-                    // matter that we
-                    // use reflection as performance is no a concern during
-                    // route building
-                    Object transactionManager = maps.values().iterator().next();
-                    LOG.debug("One instance of PlatformTransactionManager found in registry: {}", transactionManager);
-                    Class<?> txClazz = camelContext.getClassResolver()
-                            .resolveClass("org.apache.camel.spring.spi.SpringTransactionPolicy");
-                    if (txClazz != null) {
-                        LOG.debug("Creating a new temporary SpringTransactionPolicy using the PlatformTransactionManager: {}",
-                                transactionManager);
-                        TransactedPolicy txPolicy
-                                = org.apache.camel.support.ObjectHelper.newInstance(txClazz, TransactedPolicy.class);
-                        Method method;
-                        try {
-                            method = txClazz.getMethod("setTransactionManager", tmClazz);
-                        } catch (NoSuchMethodException e) {
-                            throw new RuntimeCamelException(
-                                    "Cannot get method setTransactionManager(PlatformTransactionManager) on class: " + txClazz);
-                        }
-                        org.apache.camel.support.ObjectHelper.invokeMethod(method, txPolicy, transactionManager);
-                        return txPolicy;
-                    } else {
-                        // camel-spring is missing on the classpath
+                // as we do not want dependency on spring jars in the
+                // camel-core we use
+                // reflection to lookup classes and create new objects and
+                // call methods
+                // as this is only done during route building it does not
+                // matter that we
+                // use reflection as performance is no a concern during
+                // route building
+                LOG.debug("One instance of PlatformTransactionManager found in registry: {}", transactionManager);
+                Class<?> txClazz = camelContext.getClassResolver()
+                        .resolveClass("org.apache.camel.spring.spi.SpringTransactionPolicy");
+                if (txClazz != null) {
+                    LOG.debug("Creating a new temporary SpringTransactionPolicy using the PlatformTransactionManager: {}",
+                            transactionManager);
+                    TransactedPolicy txPolicy
+                            = org.apache.camel.support.ObjectHelper.newInstance(txClazz, TransactedPolicy.class);
+                    Method method;
+                    try {
+                        method = txClazz.getMethod("setTransactionManager", tmClazz);
+                    } catch (NoSuchMethodException e) {
                         throw new RuntimeCamelException(
-                                "Cannot create a transacted policy as camel-spring.jar is not on the classpath!");
+                                "Cannot get method setTransactionManager(PlatformTransactionManager) on class: " + txClazz);
                     }
+                    org.apache.camel.support.ObjectHelper.invokeMethod(method, txPolicy, transactionManager);
+                    return txPolicy;
                 } else {
-                    if (maps.isEmpty()) {
-                        throw new NoSuchBeanException(null, "PlatformTransactionManager");
-                    } else {
-                        throw new IllegalArgumentException(
-                                "Found " + maps.size() + " PlatformTransactionManager in registry. "
-                                                           + "Cannot determine which one to use. Please configure a TransactionTemplate on the transacted policy.");
-                    }
+                    // camel-spring is missing on the classpath
+                    throw new RuntimeCamelException(
+                            "Cannot create a transacted policy as camel-spring.jar is not on the classpath!");
                 }
             }
         }
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/LogReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/LogReifier.java
index cc46df36220..a1744b48135 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/LogReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/LogReifier.java
@@ -16,8 +16,6 @@
  */
 package org.apache.camel.reifier;
 
-import java.util.Map;
-
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.LoggingLevel;
@@ -65,17 +63,8 @@ public class LogReifier extends ProcessorReifier<LogDefinition> {
         }
 
         if (logger == null) {
-            // first - try to lookup single instance in the registry, just like
-            // LogComponent
-            Map<String, Logger> availableLoggers = findByTypeWithName(Logger.class);
-            if (availableLoggers.size() == 1) {
-                logger = availableLoggers.values().iterator().next();
-                LOG.debug("Using custom Logger: {}", logger);
-            } else if (availableLoggers.size() > 1) {
-                // we should log about this somewhere...
-                LOG.debug("More than one {} instance found in the registry. Falling back to create logger by name.",
-                        Logger.class.getName());
-            }
+            // first - try to lookup single instance in the registry, just like LogComponent
+            logger = findSingleByType(Logger.class);
         }
 
         if (logger == null) {
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SagaReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SagaReifier.java
index 2aefa602b47..4900658ae54 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SagaReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SagaReifier.java
@@ -102,13 +102,7 @@ public class SagaReifier extends ProcessorReifier<SagaDefinition> {
             return sagaService;
         }
 
-        sagaService = findSingleByType(CamelSagaService.class);
-        if (sagaService != null) {
-            return sagaService;
-        }
-
-        throw new IllegalArgumentException(
-                "Cannot find CamelSagaService in Registry");
+        return mandatoryFindSingleByType(CamelSagaService.class);
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/EndpointHelperTest.java b/core/camel-core/src/test/java/org/apache/camel/util/EndpointHelperTest.java
index d11ba17b763..c22dd27ad6d 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/EndpointHelperTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/EndpointHelperTest.java
@@ -250,7 +250,7 @@ public class EndpointHelperTest extends ContextTestSupport {
                     AuthorizationPolicy.class);
             fail("Should throw exception");
         } catch (NoSuchBeanException e) {
-            assertTrue(e.getMessage().contains("Found 2 beans"));
+            // expected
         }
     }
 
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/CamelContextHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/CamelContextHelper.java
index 5a8ef88ef47..2f5a49a7093 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/CamelContextHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/CamelContextHelper.java
@@ -213,6 +213,14 @@ public final class CamelContextHelper {
         return camelContext.getRegistry().findSingleByType(type);
     }
 
+    /**
+     * Look up a bean of the give type in the {@link org.apache.camel.spi.Registry} on the {@link CamelContext} or
+     * throws {@link org.apache.camel.NoSuchBeanTypeException} if not a single bean was found.
+     */
+    public static <T> T mandatoryFindSingleByType(CamelContext camelContext, Class<T> type) {
+        return camelContext.getRegistry().mandatoryFindSingleByType(type);
+    }
+
     /**
      * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the {@link CamelContext} or throws
      * {@link NoSuchBeanException} if not found.
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
index dda837cc5e2..5cac9b3202c 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
@@ -507,10 +507,7 @@ public abstract class DefaultEndpoint extends ServiceSupport implements Endpoint
                         if (value == null) {
                             Class<?> type = getter.getOptionType(name, true);
                             if (type != null) {
-                                Set<?> set = camelContext.getRegistry().findByType(type);
-                                if (set.size() == 1) {
-                                    value = set.iterator().next();
-                                }
+                                value = camelContext.getRegistry().findSingleByType(type);
                             }
                             if (value != null) {
                                 boolean hit = configurer.configure(camelContext, this, name, value, true);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
index ae971a21714..f13cb037f01 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/EndpointHelper.java
@@ -22,7 +22,6 @@ import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.camel.CamelContext;
@@ -334,13 +333,7 @@ public final class EndpointHelper {
             try {
                 value = value.substring(6);
                 Class<?> clazz = context.getClassResolver().resolveMandatoryClass(value);
-                Set<?> set = context.getRegistry().findByType(clazz);
-                if (set.size() == 1) {
-                    answer = set.iterator().next();
-                } else if (set.size() > 1) {
-                    throw new NoSuchBeanException(
-                            value, "Found " + set.size() + " beans of type: " + clazz + ". Only 1 bean instance is supported.");
-                }
+                answer = context.getRegistry().mandatoryFindSingleByType(clazz);
             } catch (ClassNotFoundException e) {
                 throw new NoSuchBeanException(value, e);
             }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java b/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java
index e43ed8318a1..61a6e384974 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java
@@ -17,7 +17,6 @@
 package org.apache.camel.support;
 
 import java.util.Collection;
-import java.util.Set;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.function.Consumer;
 
@@ -258,10 +257,7 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy {
                     if (value == null) {
                         Class<?> type = getter.getOptionType(option, true);
                         if (type != null) {
-                            Set<?> set = camelContext.getRegistry().findByType(type);
-                            if (set.size() == 1) {
-                                value = set.iterator().next();
-                            }
+                            value = camelContext.getRegistry().findSingleByType(type);
                         }
                         if (value != null) {
                             boolean hit = pc.configure(camelContext, target, option, value, true);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index d93c9a845fd..7d766645ee1 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -855,18 +855,7 @@ public final class PropertyBindingSupport {
                     }
                 }
                 if (parameterType != null) {
-                    Set<?> types = context.getRegistry().findByType(parameterType);
-                    if (types.size() == 1) {
-                        value = types.iterator().next();
-                    } else if (types.size() > 1) {
-                        throw new IllegalStateException(
-                                "Cannot select single type: " + parameterType + " as there are " + types.size()
-                                                        + " beans in the registry with this type");
-                    } else {
-                        throw new IllegalStateException(
-                                "Cannot select single type: " + parameterType
-                                                        + " as there are no beans in the registry with this type");
-                    }
+                    value = context.getRegistry().mandatoryFindSingleByType(parameterType);
                 }
             }
         }
@@ -1611,17 +1600,7 @@ public final class PropertyBindingSupport {
             // its reference by type, so lookup the actual value and use it if there is only one instance in the registry
             String typeName = strval.substring(6);
             Class<?> type = camelContext.getClassResolver().resolveMandatoryClass(typeName);
-            Set<?> types = camelContext.getRegistry().findByType(type);
-            if (types.size() == 1) {
-                answer = types.iterator().next();
-            } else if (types.size() > 1) {
-                throw new IllegalStateException(
-                        "Cannot select single type: " + typeName + " as there are " + types.size()
-                                                + " beans in the registry with this type");
-            } else {
-                throw new IllegalStateException(
-                        "Cannot select single type: " + typeName + " as there are no beans in the registry with this type");
-            }
+            answer = camelContext.getRegistry().mandatoryFindSingleByType(type);
         } else if (strval.startsWith("#bean:")) {
             String key = strval.substring(6);
             answer = CamelContextHelper.mandatoryLookup(camelContext, key);