Skip to content

Commit 4dc406e

Browse files
fmbenhassinemminella
authored andcommitted
BATCH-2564: make AutomaticJobRegistrar implement SmartLifeCycle
Before this commit, the AutomaticJobRegistrar was started on ContextRefreshedEvent event. This is sometimes too late to register jobs especially when other life cycle components that use the jobs are started before this registrar. This commit changes the AutomaticJobRegistrar to implement SmartLifeCycle and makes its autoStartup and phase properties configurable. It should be noted that the "onApplicationEvent" method has been removed even if it is a public API. This method is not intended to be used by client code and even if it was, its usage is considered wrong anyway. Resolves BATCH-2564
1 parent b02367d commit 4dc406e

File tree

2 files changed

+65
-50
lines changed

2 files changed

+65
-50
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrar.java

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2007 the original author or authors.
2+
* Copyright 2006-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,11 +25,9 @@
2525
import org.springframework.beans.factory.InitializingBean;
2626
import org.springframework.context.ApplicationContext;
2727
import org.springframework.context.ApplicationContextAware;
28-
import org.springframework.context.ApplicationListener;
2928
import org.springframework.context.Lifecycle;
29+
import org.springframework.context.SmartLifecycle;
3030
import org.springframework.context.event.ApplicationContextEvent;
31-
import org.springframework.context.event.ContextClosedEvent;
32-
import org.springframework.context.event.ContextRefreshedEvent;
3331
import org.springframework.core.Ordered;
3432
import org.springframework.util.Assert;
3533

@@ -40,10 +38,11 @@
4038
*
4139
* @author Lucas Ward
4240
* @author Dave Syer
41+
* @author Mahmoud Ben Hassine
4342
*
4443
* @since 2.1
4544
*/
46-
public class AutomaticJobRegistrar implements Ordered, Lifecycle, ApplicationListener<ApplicationContextEvent>, ApplicationContextAware,
45+
public class AutomaticJobRegistrar implements Ordered, SmartLifecycle, ApplicationContextAware,
4746
InitializingBean {
4847

4948
private Collection<ApplicationContextFactory> applicationContextFactories = new ArrayList<ApplicationContextFactory>();
@@ -54,6 +53,10 @@ public class AutomaticJobRegistrar implements Ordered, Lifecycle, ApplicationLis
5453

5554
private volatile boolean running = false;
5655

56+
private int phase = Integer.MIN_VALUE + 1000;
57+
58+
private boolean autoStartup = true;
59+
5760
private Object lifecycleMonitor = new Object();
5861

5962
private int order = Ordered.LOWEST_PRECEDENCE;
@@ -125,25 +128,6 @@ public void afterPropertiesSet() {
125128

126129
}
127130

128-
/**
129-
* Creates all the application contexts required and set up job registry entries with all the instances of
130-
* {@link Job} found therein. Also closes the contexts when the enclosing context is closed.
131-
*
132-
* @see InitializingBean#afterPropertiesSet()
133-
*/
134-
@Override
135-
public final void onApplicationEvent(ApplicationContextEvent event) {
136-
// TODO: With Spring 3 a SmartLifecycle is started automatically
137-
if (event.getSource() == applicationContext) {
138-
if (event instanceof ContextRefreshedEvent) {
139-
start();
140-
}
141-
else if (event instanceof ContextClosedEvent) {
142-
stop();
143-
}
144-
}
145-
}
146-
147131
/**
148132
* Delegates to {@link JobLoader#clear()}.
149133
*
@@ -193,4 +177,36 @@ public boolean isRunning() {
193177
}
194178
}
195179

180+
@Override
181+
public boolean isAutoStartup() {
182+
return autoStartup;
183+
}
184+
185+
/**
186+
* @param autoStartup true for auto start.
187+
* @see #isAutoStartup()
188+
*/
189+
public void setAutoStartup(boolean autoStartup) {
190+
this.autoStartup = autoStartup;
191+
}
192+
193+
@Override
194+
public int getPhase() {
195+
return phase;
196+
}
197+
198+
/**
199+
* @param phase the phase.
200+
* @see #getPhase()
201+
*/
202+
public void setPhase(int phase) {
203+
this.phase = phase;
204+
}
205+
206+
@Override
207+
public void stop(Runnable callback) {
208+
stop();
209+
callback.run();
210+
}
211+
196212
}

spring-batch-core/src/test/java/org/springframework/batch/core/configuration/support/AutomaticJobRegistrarTests.java

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2014 the original author or authors.
2+
* Copyright 2010-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,11 +25,10 @@
2525

2626
import org.junit.Before;
2727
import org.junit.Test;
28+
import org.mockito.Mockito;
2829
import org.springframework.batch.core.Job;
2930
import org.springframework.beans.factory.BeanCreationException;
3031
import org.springframework.context.ApplicationContext;
31-
import org.springframework.context.event.ContextClosedEvent;
32-
import org.springframework.context.event.ContextRefreshedEvent;
3332
import org.springframework.context.support.ClassPathXmlApplicationContext;
3433
import org.springframework.context.support.GenericApplicationContext;
3534
import org.springframework.core.Ordered;
@@ -40,6 +39,7 @@
4039
*
4140
* @author Dave Syer
4241
* @author Lucas Ward
42+
* @author Mahmoud Ben Hassine
4343
*
4444
*/
4545
public class AutomaticJobRegistrarTests {
@@ -66,6 +66,20 @@ public void testOrderedImplemented() throws Exception {
6666

6767
}
6868

69+
@Test
70+
public void testDefaultAutoStartup() throws Exception {
71+
72+
assertTrue(registrar.isAutoStartup());
73+
74+
}
75+
76+
@Test
77+
public void testDefaultPhase() throws Exception {
78+
79+
assertEquals(Integer.MIN_VALUE + 1000, registrar.getPhase());
80+
81+
}
82+
6983
@Test
7084
public void testLocateJob() throws Exception {
7185

@@ -176,36 +190,21 @@ public void testStartStopRunning() throws Exception {
176190

177191
}
178192

179-
@SuppressWarnings("resource")
180-
@Test
181-
public void testInitCalledOnContextRefreshed() throws Exception {
182-
183-
Resource[] jobPaths = new Resource[] { new ClassPathResource(
184-
"org/springframework/batch/core/launch/support/2jobs.xml") };
185-
registrar.setApplicationContext(new ClassPathXmlApplicationContext(
186-
"/org/springframework/batch/core/launch/support/test-environment-with-registry-and-auto-register.xml"));
187-
GenericApplicationContext applicationContext = new GenericApplicationContext();
188-
applicationContext.refresh();
189-
setUpApplicationContextFactories(jobPaths, applicationContext);
190-
registrar.setApplicationContext(applicationContext);
191-
registrar.onApplicationEvent(new ContextRefreshedEvent(applicationContext));
192-
assertEquals(2, registry.getJobNames().size());
193-
}
194-
195193
@Test
196-
public void testClearCalledOnContextClosed() throws Exception {
194+
public void testStartStopRunningWithCallback() throws Exception {
197195

196+
Runnable callback = Mockito.mock(Runnable.class);
198197
Resource[] jobPaths = new Resource[] { new ClassPathResource(
199198
"org/springframework/batch/core/launch/support/2jobs.xml") };
200-
@SuppressWarnings("resource")
201-
GenericApplicationContext applicationContext = new GenericApplicationContext();
202-
applicationContext.refresh();
203-
setUpApplicationContextFactories(jobPaths, applicationContext);
204-
registrar.setApplicationContext(applicationContext);
199+
setUpApplicationContextFactories(jobPaths, null);
200+
registrar.start();
201+
assertTrue(registrar.isRunning());
205202
registrar.start();
206203
assertEquals(2, registry.getJobNames().size());
207-
registrar.onApplicationEvent(new ContextClosedEvent(applicationContext));
204+
registrar.stop(callback);
205+
assertFalse(registrar.isRunning());
208206
assertEquals(0, registry.getJobNames().size());
207+
Mockito.verify(callback, Mockito.times(1)).run();
209208

210209
}
211210

0 commit comments

Comments
 (0)