diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepListenerParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepListenerParserTests.java
index b9a199c1c..c8a873112 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepListenerParserTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepListenerParserTests.java
@@ -67,7 +67,7 @@ public class StepListenerParserTests {
}
@Test
- public void testInheritListeners_NoMerge() throws Exception {
+ public void testInheritListenersNoMerge() throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
"org/springframework/batch/core/configuration/xml/StepListenerParserTests-context.xml");
List> list = getListeners("s2", ctx);
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/StepListenerFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/StepListenerFactoryBeanTests.java
index 31de6f3a1..e868d8832 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/listener/StepListenerFactoryBeanTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/listener/StepListenerFactoryBeanTests.java
@@ -241,7 +241,9 @@ public class StepListenerFactoryBeanTests {
}
};
ProxyFactory factory = new ProxyFactory(delegate);
- assertTrue(StepListenerFactoryBean.isListener(factory.getProxy()));
+ Object proxy = factory.getProxy();
+ assertTrue(StepListenerFactoryBean.isListener(proxy));
+ ((StepExecutionListener) StepListenerFactoryBean.getListener(proxy)).beforeStep(null);
}
@Test
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SimpleMethodInvoker.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SimpleMethodInvoker.java
index 8d4ec66e6..e23766710 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SimpleMethodInvoker.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/support/SimpleMethodInvoker.java
@@ -35,13 +35,15 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.springframework.aop.framework.Advised;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
- * Simple implementation of the {@link MethodInvoker} interface that invokes a method on an
- * object. If the method has no arguments, but arguments are provided, they are ignored and the method
- * is invoked anyway. If there are more arguments than there are provided, then an exception is thrown.
+ * Simple implementation of the {@link MethodInvoker} interface that invokes a
+ * method on an object. If the method has no arguments, but arguments are
+ * provided, they are ignored and the method is invoked anyway. If there are
+ * more arguments than there are provided, then an exception is thrown.
*
* @author Lucas Ward
* @since 2.0
@@ -49,69 +51,98 @@ import org.springframework.util.ClassUtils;
public class SimpleMethodInvoker implements MethodInvoker {
private final Object object;
+
private Method method;
-
+
public SimpleMethodInvoker(Object object, Method method) {
Assert.notNull(object, "Object to invoke must not be null");
Assert.notNull(method, "Method to invoke must not be null");
- this.object = object;
this.method = method;
- }
-
- public SimpleMethodInvoker(Object object, String methodName, Class>... paramTypes){
- Assert.notNull(object, "Object to invoke must not be null");
this.object = object;
- this.method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, paramTypes);
- if(this.method == null){
- //try with no params
- this.method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, new Class[]{});
- }
- if(this.method == null){
- throw new IllegalArgumentException("No methods found for name: [" + methodName + "] in class: [" +
- object.getClass() + "] with arguments of type: [" + Arrays.toString(paramTypes) + "]");
- }
}
-
- /* (non-Javadoc)
- * @see org.springframework.batch.core.configuration.util.MethodInvoker#invokeMethod(java.lang.Object[])
+
+ public SimpleMethodInvoker(Object object, String methodName, Class>... paramTypes) {
+ Assert.notNull(object, "Object to invoke must not be null");
+ this.method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, paramTypes);
+ if (this.method == null) {
+ // try with no params
+ this.method = ClassUtils.getMethodIfAvailable(object.getClass(), methodName, new Class[] {});
+ }
+ if (this.method == null) {
+ throw new IllegalArgumentException("No methods found for name: [" + methodName + "] in class: ["
+ + object.getClass() + "] with arguments of type: [" + Arrays.toString(paramTypes) + "]");
+ }
+ this.object = object;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.springframework.batch.core.configuration.util.MethodInvoker#invokeMethod
+ * (java.lang.Object[])
*/
public Object invokeMethod(Object... args) {
-
+
Class>[] parameterTypes = method.getParameterTypes();
Object[] invokeArgs;
- if(parameterTypes.length == 0){
- invokeArgs = new Object[]{};
+ if (parameterTypes.length == 0) {
+ invokeArgs = new Object[] {};
}
- else if(parameterTypes.length != args.length){
- throw new IllegalArgumentException("Wrong number of arguments, expected no more than: [" + parameterTypes.length + "]");
+ else if (parameterTypes.length != args.length) {
+ throw new IllegalArgumentException("Wrong number of arguments, expected no more than: ["
+ + parameterTypes.length + "]");
}
- else{
+ else {
invokeArgs = args;
}
-
+
method.setAccessible(true);
-
+
try {
- return method.invoke(object, invokeArgs);
- } catch (Exception e) {
- throw new IllegalArgumentException("Unable to invoke method: [" + method + "] on object: [" +
- object + "] with arguments: [" + Arrays.toString(args) + "]", e);
- }
+ // Extract the target from an Advised as late as possible
+ // in case it contains a lazy initialization
+ Object target = extractTarget(object, method);
+ return method.invoke(target, invokeArgs);
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException("Unable to invoke method: [" + method + "] on object: [" + object
+ + "] with arguments: [" + Arrays.toString(args) + "]", e);
+ }
}
-
+
+ private Object extractTarget(Object target, Method method) {
+ if (target instanceof Advised) {
+ Object source;
+ try {
+ source = ((Advised) target).getTargetSource().getTarget();
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Could not extract target from proxy", e);
+ }
+ if (source instanceof Advised) {
+ source = extractTarget(source, method);
+ }
+ if (method.getDeclaringClass().isAssignableFrom(source.getClass())) {
+ target = source;
+ }
+ }
+ return target;
+ }
+
@Override
public boolean equals(Object obj) {
- if(!(obj instanceof SimpleMethodInvoker)){
+ if (!(obj instanceof SimpleMethodInvoker)) {
return false;
}
-
- if(obj == this){
+
+ if (obj == this) {
return true;
}
SimpleMethodInvoker rhs = (SimpleMethodInvoker) obj;
return (rhs.method.equals(this.method)) && (rhs.object.equals(this.object));
}
-
+
@Override
public int hashCode() {
return new HashCodeBuilder(25, 37).append(object.hashCode()).append(method.hashCode()).toHashCode();
diff --git a/spring-batch-samples/src/main/resources/jobs/partitionJob.xml b/spring-batch-samples/src/main/resources/jobs/partitionJob.xml
index a91bcf92c..a3d46571c 100644
--- a/spring-batch-samples/src/main/resources/jobs/partitionJob.xml
+++ b/spring-batch-samples/src/main/resources/jobs/partitionJob.xml
@@ -45,7 +45,7 @@
-
+