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 2012/06/25 17:41:59 UTC
svn commit: r1353601 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/language/bean/
main/java/org/apache/camel/model/language/
test/java/org/apache/camel/component/bean/
Author: davsclaus
Date: Mon Jun 25 15:41:57 2012
New Revision: 1353601
URL: http://svn.apache.org/viewvc?rev=1353601&view=rev
Log:
CAMEL-5392: Optimized bean expression to reuse bean holder to avoid re-introspecting the bean on subsequent evaluations. Thanks to Mark Hillary for the patch.
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExpressionConcurrentTest.java
- copied, changed from r1353590, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanConcurrentTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java?rev=1353601&r1=1353600&r2=1353601&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java Mon Jun 25 15:41:57 2012
@@ -19,6 +19,7 @@ package org.apache.camel.language.bean;
import java.util.List;
import java.util.Map;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
@@ -37,28 +38,41 @@ import org.apache.camel.util.StringHelpe
/**
* Evaluates an expression using a bean method invocation
- *
- * @version
*/
public class BeanExpression implements Expression, Predicate {
- private Object bean;
- private String beanName;
- private Class<?> type;
- private String method;
+ private final Object bean;
+ private final String beanName;
+ private final Class<?> type;
+ private final String method;
+ private volatile BeanHolder beanHolder;
public BeanExpression(Object bean, String method) {
this.bean = bean;
this.method = method;
+ this.beanName = null;
+ this.type = null;
}
public BeanExpression(String beanName, String method) {
this.beanName = beanName;
this.method = method;
+ this.bean = null;
+ this.type = null;
}
public BeanExpression(Class<?> type, String method) {
this.type = type;
this.method = method;
+ this.bean = null;
+ this.beanName = null;
+ }
+
+ public BeanExpression(BeanHolder beanHolder, String method) {
+ this.beanHolder = beanHolder;
+ this.method = method;
+ this.bean = null;
+ this.beanName = null;
+ this.type = null;
}
@Override
@@ -79,16 +93,10 @@ public class BeanExpression implements E
}
public Object evaluate(Exchange exchange) {
- // either use registry lookup or a constant bean
- BeanHolder holder;
- if (bean != null) {
- holder = new ConstantBeanHolder(bean, exchange.getContext());
- } else if (beanName != null) {
- holder = new RegistryBean(exchange.getContext(), beanName);
- } else if (type != null) {
- holder = new ConstantTypeBeanHolder(type, exchange.getContext());
- } else {
- throw new IllegalArgumentException("Either bean, beanName or type should be set on " + this);
+
+ // if the bean holder doesn't exist then create it using the context from the exchange
+ if (beanHolder == null) {
+ beanHolder = createBeanHolder(exchange.getContext());
}
// invoking the bean can either be the easy way or using OGNL
@@ -101,7 +109,7 @@ public class BeanExpression implements E
if (OgnlHelper.isValidOgnlExpression(method)) {
// okay the method is an ognl expression
- OgnlInvokeProcessor ognl = new OgnlInvokeProcessor(holder, method);
+ OgnlInvokeProcessor ognl = new OgnlInvokeProcessor(beanHolder, method);
try {
ognl.process(exchange);
return ognl.getResult();
@@ -110,7 +118,7 @@ public class BeanExpression implements E
}
} else {
// regular non ognl invocation
- InvokeProcessor invoke = new InvokeProcessor(holder, method);
+ InvokeProcessor invoke = new InvokeProcessor(beanHolder, method);
try {
invoke.process(exchange);
return invoke.getResult();
@@ -131,6 +139,25 @@ public class BeanExpression implements E
}
/**
+ * Optimize to create the bean holder once, so we can reuse it for further
+ * evaluation, which is faster.
+ */
+ private synchronized BeanHolder createBeanHolder(CamelContext context) {
+ // either use registry lookup or a constant bean
+ BeanHolder holder;
+ if (bean != null) {
+ holder = new ConstantBeanHolder(bean, context);
+ } else if (beanName != null) {
+ holder = new RegistryBean(context, beanName);
+ } else if (type != null) {
+ holder = new ConstantTypeBeanHolder(type, context);
+ } else {
+ throw new IllegalArgumentException("Either bean, beanName or type should be set on " + this);
+ }
+ return holder;
+ }
+
+ /**
* Invokes a given bean holder. The method name is optional.
*/
private final class InvokeProcessor implements Processor {
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java?rev=1353601&r1=1353600&r2=1353601&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java Mon Jun 25 15:41:57 2012
@@ -28,6 +28,8 @@ import org.apache.camel.ExpressionIllega
import org.apache.camel.Predicate;
import org.apache.camel.component.bean.BeanHolder;
import org.apache.camel.component.bean.BeanInfo;
+import org.apache.camel.component.bean.ConstantBeanHolder;
+import org.apache.camel.component.bean.ConstantTypeBeanHolder;
import org.apache.camel.component.bean.MethodNotFoundException;
import org.apache.camel.component.bean.RegistryBean;
import org.apache.camel.language.bean.BeanExpression;
@@ -38,7 +40,7 @@ import org.apache.camel.util.OgnlHelper;
* For expressions and predicates using the
* <a href="http://camel.apache.org/bean-language.html">bean language</a>
*
- * @version
+ * @version
*/
@XmlRootElement(name = "method")
@XmlAccessorType(XmlAccessType.FIELD)
@@ -68,11 +70,11 @@ public class MethodCallExpression extend
super(beanName);
this.method = method;
}
-
+
public MethodCallExpression(Object instance) {
this(instance, null);
}
-
+
public MethodCallExpression(Object instance, String method) {
super(ObjectHelper.className(instance));
// must use setter as they have special logic
@@ -83,7 +85,7 @@ public class MethodCallExpression extend
public MethodCallExpression(Class<?> type) {
this(type, null);
}
-
+
public MethodCallExpression(Class<?> type, String method) {
super(type.getName());
this.beanType = type;
@@ -162,25 +164,30 @@ public class MethodCallExpression extend
}
}
+ BeanHolder holder;
if (beanType != null) {
// create a bean if there is a default public no-arg constructor
if (ObjectHelper.hasDefaultPublicNoArgConstructor(beanType)) {
instance = camelContext.getInjector().newInstance(beanType);
- answer = new BeanExpression(instance, getMethod());
+ holder = new ConstantBeanHolder(instance, camelContext);
} else {
- answer = new BeanExpression(beanType, getMethod());
+ holder = new ConstantTypeBeanHolder(beanType, camelContext);
}
} else if (instance != null) {
- answer = new BeanExpression(instance, getMethod());
+ holder = new ConstantBeanHolder(instance, camelContext);
} else {
String ref = beanName();
// if its a ref then check that the ref exists
- BeanHolder holder = new RegistryBean(camelContext, ref);
+ BeanHolder regHolder = new RegistryBean(camelContext, ref);
// get the bean which will check that it exists
- instance = holder.getBean();
- answer = new BeanExpression(instance, getMethod());
+ instance = regHolder.getBean();
+ holder = new ConstantBeanHolder(instance, camelContext);
}
+ // create answer using the holder
+ answer = new BeanExpression(holder, getMethod());
+
+ // and do sanity check that if a method name was given, that it exists
validateHasMethod(camelContext, instance, beanType, getMethod());
return answer;
}
Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExpressionConcurrentTest.java (from r1353590, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanConcurrentTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExpressionConcurrentTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExpressionConcurrentTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanConcurrentTest.java&r1=1353590&r2=1353601&rev=1353601&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanConcurrentTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanExpressionConcurrentTest.java Mon Jun 25 15:41:57 2012
@@ -28,7 +28,7 @@ import org.apache.camel.impl.JndiRegistr
/**
* @version
*/
-public class BeanConcurrentTest extends ContextTestSupport {
+public class BeanExpressionConcurrentTest extends ContextTestSupport {
public void testBeanConcurrent() throws Exception {
MockEndpoint mock = getMockEndpoint("mock:result");
@@ -75,7 +75,7 @@ public class BeanConcurrentTest extends
@Override
public void configure() throws Exception {
from("seda:foo?concurrentConsumers=10").routeId("foo").noAutoStartup()
- .to("bean:myBean")
+ .transform(method("myBean"))
.to("mock:result");
}
};