Skip to content

Commit b42aa87

Browse files
mminellazjouahri
authored and
zjouahri
committed
Added end of job listener
Spring Batch jobs are executed via Spring Boot's JobLaunchingCommandLineRunner. This guide also uses a CommandLineRunner to verify the results of the job. This can cause state inconsistencies between the two (job may run before or after the queries). This commit adds a JobExecutionListener that decrements a CountdownLatch. The queries wait for the latch to complete guaranteeing that the job has completed. Github Issue 8
1 parent 09a1795 commit b42aa87

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

complete/src/main/java/hello/Application.java

+8-11
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,25 @@
33
import java.sql.ResultSet;
44
import java.sql.SQLException;
55
import java.util.List;
6+
import java.util.concurrent.CountDownLatch;
67

7-
import org.springframework.beans.factory.annotation.Autowired;
8-
import org.springframework.boot.CommandLineRunner;
98
import org.springframework.boot.SpringApplication;
109
import org.springframework.boot.autoconfigure.SpringBootApplication;
10+
import org.springframework.context.ApplicationContext;
1111
import org.springframework.jdbc.core.JdbcTemplate;
1212
import org.springframework.jdbc.core.RowMapper;
1313

1414
@SpringBootApplication
15-
public class Application implements CommandLineRunner {
15+
public class Application {
1616

17-
public static void main(String[] args) {
18-
SpringApplication.run(Application.class, args);
19-
}
17+
public static void main(String[] args) throws Exception {
18+
ApplicationContext ctx = SpringApplication.run(Application.class, args);
2019

21-
@Autowired
22-
JdbcTemplate jdbcTemplate;
20+
CountDownLatch countDownLatch = ctx.getBean(CountDownLatch.class);
2321

24-
@Override
25-
public void run(String... strings) throws Exception {
22+
countDownLatch.await();
2623

27-
List<Person> results = jdbcTemplate.query("SELECT first_name, last_name FROM people", new RowMapper<Person>() {
24+
List<Person> results = ctx.getBean(JdbcTemplate.class).query("SELECT first_name, last_name FROM people", new RowMapper<Person>() {
2825
@Override
2926
public Person mapRow(ResultSet rs, int row) throws SQLException {
3027
return new Person(rs.getString(1), rs.getString(2));

complete/src/main/java/hello/BatchConfiguration.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package hello;
22

3+
import java.util.concurrent.CountDownLatch;
4+
35
import javax.sql.DataSource;
46

57
import org.springframework.batch.core.Job;
8+
import org.springframework.batch.core.JobExecutionListener;
69
import org.springframework.batch.core.Step;
710
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
811
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
@@ -26,6 +29,16 @@
2629
@EnableBatchProcessing
2730
public class BatchConfiguration {
2831

32+
@Bean
33+
public CountDownLatch countDownLatch() {
34+
return new CountDownLatch(1);
35+
}
36+
37+
@Bean
38+
public JobExecutionListener jobExecutionListener(CountDownLatch countDownLatch) {
39+
return new JobCompletionNotificationListener(countDownLatch);
40+
}
41+
2942
// tag::readerwriterprocessor[]
3043
@Bean
3144
public ItemReader<Person> reader() {
@@ -59,9 +72,10 @@ public ItemWriter<Person> writer(DataSource dataSource) {
5972

6073
// tag::jobstep[]
6174
@Bean
62-
public Job importUserJob(JobBuilderFactory jobs, Step s1) {
75+
public Job importUserJob(JobBuilderFactory jobs, Step s1, JobExecutionListener listener) {
6376
return jobs.get("importUserJob")
6477
.incrementer(new RunIdIncrementer())
78+
.listener(listener)
6579
.flow(s1)
6680
.end()
6781
.build();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package hello;
17+
18+
import java.util.concurrent.CountDownLatch;
19+
20+
import org.springframework.batch.core.BatchStatus;
21+
import org.springframework.batch.core.JobExecution;
22+
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
23+
import org.springframework.util.Assert;
24+
25+
/**
26+
* @author Michael Minella
27+
*/
28+
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
29+
30+
private CountDownLatch countDownLatch;
31+
32+
public JobCompletionNotificationListener(CountDownLatch countDownLatch) {
33+
Assert.notNull(countDownLatch);
34+
35+
this.countDownLatch = countDownLatch;
36+
}
37+
38+
@Override
39+
public void afterJob(JobExecution jobExecution) {
40+
if(jobExecution.getStatus() == BatchStatus.COMPLETED) {
41+
countDownLatch.countDown();
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)