diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
index de0b28ee8..7e963fccd 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/CoreNamespaceHandler.java
@@ -34,6 +34,7 @@ public class CoreNamespaceHandler extends NamespaceHandlerSupport {
this.registerBeanDefinitionParser("step", new TopLevelStepParser());
this.registerBeanDefinitionParser("tasklet", new TopLevelTaskletElementParser());
this.registerBeanDefinitionParser("job-repository", new JobRepositoryParser());
+ this.registerBeanDefinitionParser("job-listener", new TopLevelJobListenerParser());
this.registerBeanDefinitionParser("step-listener", new TopLevelStepListenerParser());
}
}
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/TopLevelJobListenerParser.java b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/TopLevelJobListenerParser.java
new file mode 100644
index 000000000..784cb550d
--- /dev/null
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/configuration/xml/TopLevelJobListenerParser.java
@@ -0,0 +1,29 @@
+package org.springframework.batch.core.configuration.xml;
+
+import org.springframework.batch.core.listener.AbstractListenerFactoryBean;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * Parse <job-listener/> elements in the batch namespace.
+ *
+ * @author Dan Garrette
+ * @since 2.0
+ */
+public class TopLevelJobListenerParser extends AbstractSingleBeanDefinitionParser {
+
+ private JobExecutionListenerParser jobListenerParser = new JobExecutionListenerParser();
+
+ @Override
+ protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ jobListenerParser.doParse(element, parserContext, builder);
+ }
+
+ @Override
+ protected Class extends AbstractListenerFactoryBean> getBeanClass(Element element) {
+ return jobListenerParser.getBeanClass();
+ }
+
+}
diff --git a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd
index b6e0a4d5e..04bb8288e 100644
--- a/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd
+++ b/spring-batch-core/src/main/resources/org/springframework/batch/core/configuration/xml/spring-batch-2.0.xsd
@@ -75,6 +75,20 @@
+
+
+
+ A reference to a JobExecutionListener or a POJO
+ (with before-job-method / after-job-method).
+
+
+
+
+
+
+
+
+
@@ -260,36 +274,7 @@
-
-
-
-
-
-
- A reference to a JobExecutionListener or a POJO
- (with before-job-method / after-job-method).
-
-
-
-
-
-
-
-
-
- A class name used to create a listener from the default constructor.
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -329,7 +314,7 @@
-
+
@@ -543,12 +528,41 @@
-
+
+
+
+
+
+
+ A reference to a JobExecutionListener or a POJO
+ (with before-job-method / after-job-method).
+
+
+
+
+
+
+
+
+
+ A class name used to create a job execution listener from the default constructor.
+
+
+
+
+
+
+
+
+
+
+
+
@@ -592,22 +606,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserTests.java
index afb9f2f9d..c858fa885 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/JobParserTests.java
@@ -74,6 +74,26 @@ public class JobParserTests {
assertTrue(c);
}
+ @Test
+ public void testStandaloneListener() throws Exception {
+ ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
+ "org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml");
+ List> jobListeners = getListeners("job3", ctx);
+ assertEquals(2, jobListeners.size());
+ boolean a = false;
+ boolean b = false;
+ for (Object l : jobListeners) {
+ if (l instanceof DummyAnnotationJobExecutionListener) {
+ a = true;
+ }
+ else if (l instanceof JobExecutionListenerSupport) {
+ b = true;
+ }
+ }
+ assertTrue(a);
+ assertTrue(b);
+ }
+
@SuppressWarnings("unchecked")
private List> getListeners(String jobName, ApplicationContext ctx) throws Exception {
Map beans = ctx.getBeansOfType(Job.class);
diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml
index 9a28af00a..d4e7da248 100644
--- a/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml
+++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/configuration/xml/JobParserParentAttributeTests-context.xml
@@ -22,10 +22,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file