Skip to content

Commit 5c0b33f

Browse files
committed
Support interface based listener registration
1 parent 425134c commit 5c0b33f

File tree

10 files changed

+257
-85
lines changed

10 files changed

+257
-85
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ protected JobRepository getJobRepository() {
261261
* @throws JobExecutionException to signal a fatal batch framework error (not a
262262
* business or validation exception)
263263
*/
264-
abstract protected void doExecute(JobExecution execution) throws JobExecutionException;
264+
protected abstract void doExecute(JobExecution execution) throws JobExecutionException;
265265

266266
/**
267267
* Run the specified job, handling all listener and repository calls, and delegating

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,14 @@
1515
*/
1616
package org.springframework.batch.core.job.builder;
1717

18-
import java.lang.reflect.Method;
18+
import java.lang.annotation.Annotation;
1919
import java.util.ArrayList;
20-
import java.util.HashSet;
2120
import java.util.LinkedHashSet;
2221
import java.util.List;
2322
import java.util.Set;
2423

25-
import io.micrometer.core.instrument.MeterRegistry;
26-
import io.micrometer.observation.ObservationRegistry;
2724
import org.apache.commons.logging.Log;
2825
import org.apache.commons.logging.LogFactory;
29-
3026
import org.springframework.batch.core.JobExecutionListener;
3127
import org.springframework.batch.core.JobParametersIncrementer;
3228
import org.springframework.batch.core.JobParametersValidator;
@@ -39,13 +35,17 @@
3935
import org.springframework.batch.core.repository.JobRepository;
4036
import org.springframework.batch.support.ReflectionUtils;
4137

38+
import io.micrometer.core.instrument.MeterRegistry;
39+
import io.micrometer.observation.ObservationRegistry;
40+
4241
/**
4342
* A base class and utility for other job builders providing access to common properties
4443
* like job repository.
4544
*
4645
* @author Dave Syer
4746
* @author Mahmoud Ben Hassine
4847
* @author Taeik Lim
48+
* @author Seonkyo Ok
4949
* @since 2.2
5050
*/
5151
public abstract class JobBuilderHelper<B extends JobBuilderHelper<B>> {
@@ -167,14 +167,10 @@ public B meterRegistry(MeterRegistry meterRegistry) {
167167
* @return this for fluent chaining
168168
*/
169169
public B listener(Object listener) {
170-
Set<Method> jobExecutionListenerMethods = new HashSet<>();
171-
jobExecutionListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeJob.class));
172-
jobExecutionListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterJob.class));
173-
174-
if (jobExecutionListenerMethods.size() > 0) {
175-
JobListenerFactoryBean factory = new JobListenerFactoryBean();
176-
factory.setDelegate(listener);
177-
properties.addJobExecutionListener((JobExecutionListener) factory.getObject());
170+
final List<Class<? extends Annotation>> targetAnnotations = List.of(BeforeJob.class, AfterJob.class);
171+
if (listener instanceof JobExecutionListener ||
172+
ReflectionUtils.hasMethodWithAnyAnnotation(listener.getClass(), targetAnnotations)) {
173+
properties.addJobExecutionListener(JobListenerFactoryBean.getListener(listener));
178174
}
179175

180176
@SuppressWarnings("unchecked")

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*/
1616
package org.springframework.batch.core.step.builder;
1717

18-
import java.lang.reflect.Method;
19-
import java.util.HashSet;
18+
import java.lang.annotation.Annotation;
2019
import java.util.LinkedHashSet;
20+
import java.util.List;
2121
import java.util.Set;
2222

2323
import org.springframework.batch.core.ChunkListener;
@@ -50,6 +50,7 @@
5050
* @author Michael Minella
5151
* @author Mahmoud Ben Hassine
5252
* @author Ilpyo Yang
53+
* @author Seonkyo Ok
5354
* @since 2.2
5455
* @param <B> the type of builder represented
5556
*/
@@ -175,15 +176,11 @@ public B listener(ChunkListener listener) {
175176
public B listener(Object listener) {
176177
super.listener(listener);
177178

178-
Set<Method> chunkListenerMethods = new HashSet<>();
179-
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeChunk.class));
180-
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterChunk.class));
181-
chunkListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterChunkError.class));
182-
183-
if (!chunkListenerMethods.isEmpty()) {
184-
StepListenerFactoryBean factory = new StepListenerFactoryBean();
185-
factory.setDelegate(listener);
186-
this.listener((ChunkListener) factory.getObject());
179+
final List<Class<? extends Annotation>> targetAnnotations = List.of(
180+
BeforeChunk.class, AfterChunk.class, AfterChunkError.class);
181+
if (listener instanceof ChunkListener ||
182+
ReflectionUtils.hasMethodWithAnyAnnotation(listener.getClass(), targetAnnotations)) {
183+
this.listener((ChunkListener) StepListenerFactoryBean.getListener(listener));
187184
}
188185

189186
return self();

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/FaultTolerantStepBuilder.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.batch.core.step.builder;
1717

18-
import java.lang.reflect.Method;
18+
import java.lang.annotation.Annotation;
1919
import java.util.ArrayList;
2020
import java.util.Collection;
2121
import java.util.HashMap;
@@ -90,6 +90,7 @@
9090
* @author Chris Schaefer
9191
* @author Michael Minella
9292
* @author Mahmoud Ben Hassine
93+
* @author Seonkyo Ok
9394
* @since 2.2
9495
*/
9596
public class FaultTolerantStepBuilder<I, O> extends SimpleStepBuilder<I, O> {
@@ -194,15 +195,11 @@ protected Tasklet createTasklet() {
194195
public FaultTolerantStepBuilder<I, O> listener(Object listener) {
195196
super.listener(listener);
196197

197-
Set<Method> skipListenerMethods = new HashSet<>();
198-
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInRead.class));
199-
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInProcess.class));
200-
skipListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnSkipInWrite.class));
201-
202-
if (!skipListenerMethods.isEmpty()) {
203-
StepListenerFactoryBean factory = new StepListenerFactoryBean();
204-
factory.setDelegate(listener);
205-
skipListeners.add((SkipListener<I, O>) factory.getObject());
198+
final List<Class<? extends Annotation>> targetAnnotations = List.of(
199+
OnSkipInRead.class, OnSkipInProcess.class, OnSkipInWrite.class);
200+
if (listener instanceof SkipListener<?,?> ||
201+
ReflectionUtils.hasMethodWithAnyAnnotation(listener.getClass(), targetAnnotations)) {
202+
skipListeners.add((SkipListener<I, O>) StepListenerFactoryBean.getListener(listener));
206203
}
207204

208205
return this;

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,12 @@
1515
*/
1616
package org.springframework.batch.core.step.builder;
1717

18-
import java.lang.reflect.Method;
18+
import java.lang.annotation.Annotation;
1919
import java.util.ArrayList;
20-
import java.util.HashSet;
2120
import java.util.LinkedHashSet;
21+
import java.util.List;
2222
import java.util.Set;
2323

24-
import io.micrometer.core.instrument.MeterRegistry;
25-
import io.micrometer.core.instrument.Metrics;
26-
2724
import org.springframework.batch.core.ChunkListener;
2825
import org.springframework.batch.core.ItemProcessListener;
2926
import org.springframework.batch.core.ItemReadListener;
@@ -56,6 +53,9 @@
5653
import org.springframework.batch.support.ReflectionUtils;
5754
import org.springframework.util.Assert;
5855

56+
import io.micrometer.core.instrument.MeterRegistry;
57+
import io.micrometer.core.instrument.Metrics;
58+
5959
/**
6060
* Step builder for simple item processing (chunk oriented) steps. Items are read and
6161
* cached in chunks, and then processed (transformed) and written (optionally the
@@ -65,6 +65,7 @@
6565
* @author Dave Syer
6666
* @author Mahmoud Ben Hassine
6767
* @author Parikshit Dutta
68+
* @author Seonkyo Ok
6869
* @since 2.2
6970
*/
7071
public class SimpleStepBuilder<I, O> extends AbstractTaskletStepBuilder<SimpleStepBuilder<I, O>> {
@@ -258,21 +259,15 @@ public SimpleStepBuilder<I, O> readerIsTransactionalQueue() {
258259
public SimpleStepBuilder<I, O> listener(Object listener) {
259260
super.listener(listener);
260261

261-
Set<Method> itemListenerMethods = new HashSet<>();
262-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeRead.class));
263-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterRead.class));
264-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeProcess.class));
265-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterProcess.class));
266-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeWrite.class));
267-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterWrite.class));
268-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnReadError.class));
269-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnProcessError.class));
270-
itemListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), OnWriteError.class));
271-
272-
if (!itemListenerMethods.isEmpty()) {
273-
StepListenerFactoryBean factory = new StepListenerFactoryBean();
274-
factory.setDelegate(listener);
275-
itemListeners.add((StepListener) factory.getObject());
262+
final List<Class<? extends Annotation>> targetAnnotations = List.of(
263+
BeforeRead.class, AfterRead.class, OnReadError.class,
264+
BeforeProcess.class, AfterProcess.class, OnProcessError.class,
265+
BeforeWrite.class, AfterWrite.class, OnWriteError.class);
266+
if (listener instanceof ItemReadListener<?> ||
267+
listener instanceof ItemProcessListener<?, ?> ||
268+
listener instanceof ItemWriteListener<?> ||
269+
ReflectionUtils.hasMethodWithAnyAnnotation(listener.getClass(), targetAnnotations)) {
270+
itemListeners.add(StepListenerFactoryBean.getListener(listener));
276271
}
277272

278273
return this;

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@
1515
*/
1616
package org.springframework.batch.core.step.builder;
1717

18-
import java.lang.reflect.Method;
18+
import java.lang.annotation.Annotation;
1919
import java.util.ArrayList;
20-
import java.util.HashSet;
2120
import java.util.List;
22-
import java.util.Set;
2321

24-
import io.micrometer.core.instrument.MeterRegistry;
25-
import io.micrometer.core.instrument.Metrics;
26-
import io.micrometer.observation.ObservationRegistry;
2722
import org.apache.commons.logging.Log;
2823
import org.apache.commons.logging.LogFactory;
29-
3024
import org.springframework.batch.core.StepExecutionListener;
3125
import org.springframework.batch.core.annotation.AfterStep;
3226
import org.springframework.batch.core.annotation.BeforeStep;
@@ -37,6 +31,10 @@
3731
import org.springframework.batch.core.step.AbstractStep;
3832
import org.springframework.batch.support.ReflectionUtils;
3933

34+
import io.micrometer.core.instrument.MeterRegistry;
35+
import io.micrometer.core.instrument.Metrics;
36+
import io.micrometer.observation.ObservationRegistry;
37+
4038
/**
4139
* A base class and utility for other step builders providing access to common properties
4240
* like job repository and listeners.
@@ -45,6 +43,7 @@
4543
* @author Michael Minella
4644
* @author Taeik Lim
4745
* @author Mahmoud Ben Hassine
46+
* @author Seonkyo Ok
4847
* @since 2.2
4948
*/
5049
public abstract class StepBuilderHelper<B extends StepBuilderHelper<B>> {
@@ -129,14 +128,10 @@ public B startLimit(int startLimit) {
129128
* @return this for fluent chaining
130129
*/
131130
public B listener(Object listener) {
132-
Set<Method> stepExecutionListenerMethods = new HashSet<>();
133-
stepExecutionListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), BeforeStep.class));
134-
stepExecutionListenerMethods.addAll(ReflectionUtils.findMethod(listener.getClass(), AfterStep.class));
135-
136-
if (stepExecutionListenerMethods.size() > 0) {
137-
StepListenerFactoryBean factory = new StepListenerFactoryBean();
138-
factory.setDelegate(listener);
139-
properties.addStepExecutionListener((StepExecutionListener) factory.getObject());
131+
final List<Class<? extends Annotation>> targetAnnotations = List.of(BeforeStep.class, AfterStep.class);
132+
if (listener instanceof StepExecutionListener ||
133+
ReflectionUtils.hasMethodWithAnyAnnotation(listener.getClass(), targetAnnotations)) {
134+
properties.addStepExecutionListener((StepExecutionListener) StepListenerFactoryBean.getListener(listener));
140135
}
141136

142137
return self();

0 commit comments

Comments
 (0)