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
The following commit(s) were added to refs/heads/master by this push:
new 10327d7 CAMEL-15217: Bean EIP should lookup in registry and use
existing single bean instance if using class as bean type. Also add better
error message if the bean type is an interface.
10327d7 is described below
commit 10327d707c4bb4c50763fd802b3116bf7f41c987
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jun 19 11:05:58 2020 +0200
CAMEL-15217: Bean EIP should lookup in registry and use existing single
bean instance if using class as bean type. Also add better error message if the
bean type is an interface.
---
.../bean/DefaultBeanProcessorFactory.java | 20 ++++-
.../bean/BeanClassTypeUseBeanFromRegistryTest.java | 85 ++++++++++++++++++++++
.../bean/{MyFooBean.java => FooService.java} | 10 +--
.../org/apache/camel/component/bean/MyFooBean.java | 2 +-
4 files changed, 107 insertions(+), 10 deletions(-)
diff --git
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java
index a56edc2..c53d682 100644
---
a/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java
+++
b/components/camel-bean/src/main/java/org/apache/camel/component/bean/DefaultBeanProcessorFactory.java
@@ -17,6 +17,7 @@
package org.apache.camel.component.bean;
import java.lang.reflect.Method;
+import java.util.Set;
import org.apache.camel.BeanScope;
import org.apache.camel.CamelContext;
@@ -83,8 +84,21 @@ public final class DefaultBeanProcessorFactory implements
BeanProcessorFactory {
clazz = beanClass;
}
+ if (scope == BeanScope.Singleton && clazz != null) {
+ // attempt to lookup in registry by type to favour using
it (like bean ref would do to lookup in registry)
+ Set<?> beans =
camelContext.getRegistry().findByType(clazz);
+ if (beans.size() > 0) {
+ if (beans.size() == 1) {
+ LOG.debug("Exactly one instance of type: {} in
registry found.", clazz);
+ bean = beans.iterator().next();
+ } else {
+ LOG.debug("Found {} bean instances of type: {} in
the registry.", beans.size(), clazz);
+ }
+ }
+ }
+
// attempt to create bean using injector which supports
auto-wiring
- if (scope == BeanScope.Singleton &&
camelContext.getInjector().supportsAutoWiring()) {
+ if (bean == null && scope == BeanScope.Singleton &&
camelContext.getInjector().supportsAutoWiring()) {
try {
LOG.debug("Attempting to create new bean instance from
class: {} via auto-wiring enabled", clazz);
bean = CamelContextHelper.newInstance(camelContext,
clazz);
@@ -118,6 +132,10 @@ public final class DefaultBeanProcessorFactory implements
BeanProcessorFactory {
} else {
if (ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
beanHolder = new ConstantTypeBeanHolder(clazz,
camelContext);
+ } else if (clazz.isInterface()) {
+ throw new IllegalArgumentException("The bean is an
interface type: " + clazz
+ + ". Interfaces are only supported to lookup
in the Camel registry for a single instance of such type."
+ + " Otherwise the bean must be a class type.");
} else {
// this is only for invoking static methods on the bean
beanHolder = new ConstantStaticTypeBeanHolder(clazz,
camelContext);
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanClassTypeUseBeanFromRegistryTest.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanClassTypeUseBeanFromRegistryTest.java
new file mode 100644
index 0000000..c9229f7
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/BeanClassTypeUseBeanFromRegistryTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.component.bean;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.FailedToCreateRouteException;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class BeanClassTypeUseBeanFromRegistryTest extends ContextTestSupport {
+
+ @Override
+ public boolean isUseRouteBuilder() {
+ return false;
+ }
+
+ @Test
+ public void testOneInstanceInRegistry() throws Exception {
+ context.getRegistry().bind("foo", new MyFooBean());
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start").bean(FooService.class).to("mock:result");
+ }
+ });
+ context.start();
+
+ getMockEndpoint("mock:result").expectedBodiesReceived("Hello Camel");
+
+ template.sendBody("direct:start", "Camel");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testTwoInstancesInRegistry() throws Exception {
+ context.getRegistry().bind("foo", new MyFooBean());
+ context.getRegistry().bind("bar", new MyFooBean());
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start").bean(FooService.class).to("mock:result");
+ }
+ });
+ try {
+ context.start();
+ fail("Should throw exception");
+ } catch (FailedToCreateRouteException e) {
+ assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+ }
+ }
+
+ @Test
+ public void testZeroInstancesInRegistry() throws Exception {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start").bean(FooService.class).to("mock:result");
+ }
+ });
+ try {
+ context.start();
+ fail("Should throw exception");
+ } catch (FailedToCreateRouteException e) {
+ assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+ }
+ }
+
+}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/FooService.java
similarity index 82%
copy from
core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
copy to
core/camel-core/src/test/java/org/apache/camel/component/bean/FooService.java
index 2bd00a0..57a7798 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/FooService.java
@@ -16,14 +16,8 @@
*/
package org.apache.camel.component.bean;
-public class MyFooBean {
+public interface FooService {
- public String hello(String s) {
- return "Hello " + s;
- }
+ String hello(String s);
- @Override
- public String toString() {
- return "MyFooBean";
- }
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
b/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
index 2bd00a0..0ed3e73 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/bean/MyFooBean.java
@@ -16,7 +16,7 @@
*/
package org.apache.camel.component.bean;
-public class MyFooBean {
+public class MyFooBean implements FooService {
public String hello(String s) {
return "Hello " + s;