Spring Batch_Intercepting Job Execution

本文介绍如何使用 Spring Batch 的 JobExecutionListener 接口来监听并处理 Job 的开始和结束事件。通过示例展示了如何配置监听器,并提供了一个简单的 Java 类实现,用于打印 Job 的启动和完成状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Batch_Intercepting Job Execution_配置JobExecutionListener


关于spring batch skip 的配置请看:http://my.oschina.net/xinxingegeya/blog/346244

在job的运行期间,我们可以捕捉job 的运行开始和结束,这些都是通过配置job 的listener 实现的。

如下配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
< beans  xmlns = "http://www.springframework.org/schema/beans"
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"  xmlns:batch = "http://www.springframework.org/schema/batch"
     xmlns:context = "http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
         http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
     <!-- 包的扫描 -->
     < context:component-scan  base-package = "com.lyx.batch"  />
 
     < bean  id = "exceptionHandler"  class = "com.lyx.batch.ExceptionListener"  />
 
     < batch:step  id = "abstractStep"  abstract = "true" >
         < batch:listeners >
             < batch:listener  ref = "exceptionHandler"  />
         </ batch:listeners >
     </ batch:step >
     < bean  id = "abstractCursorReader"  abstract = "true"
         class = "org.springframework.batch.item.database.JdbcCursorItemReader" >
         < property  name = "dataSource"  ref = "dataSource"  />
     </ bean >
 
     <!-- add people desc job begin -->
     < batch:job  id = "addPeopleDescJob" >
         < batch:step  id = "addDescStep"  parent = "abstractStep" >
             < batch:tasklet >
                 < batch:chunk  reader = "peopleAddDescReader"  processor = "allowSkipProcessor"
                     writer = "addDescPeopleWriter"  commit-interval = "2"  skip-limit = "10" >
                     < batch:skippable-exception-classes >
                         <!--batch:include配置允许发生的异常 -->
                         < batch:include  class = "com.lyx.batch.InvalidDataException"  />
                     </ batch:skippable-exception-classes >
                 </ batch:chunk >
             </ batch:tasklet >
         </ batch:step >
         <!-- 在job的运行期间,可以监视job -->
         < batch:listeners >
             < batch:listener  ref = "sampleListener"  />
         </ batch:listeners >
     </ batch:job >
     <!-- add people desc job end -->
     < bean  id = "sampleListener"  class = "com.lyx.batch3.SampleJobExecutionListener"  />
 
     < bean  id = "peopleAddDescReader"  parent = "abstractCursorReader"
         scope = "step" >
         < property  name = "sql" >
             < value > <![CDATA[select first_name ,last_name from people where 
             first_name like ? or last_name like ?]]> </ value >
         </ property >
         < property  name = "rowMapper"  ref = "peopleRowMapper"  />
         < property  name = "preparedStatementSetter"  ref = "preparedStatementSetter"  />
         < property  name = "fetchSize"  value = "20"  />
     </ bean >
     < bean  id = "peopleRowMapper"  class = "com.lyx.batch.PeopleRowMapper"  />
     < bean  id = "preparedStatementSetter"  class = "com.lyx.batch.PeoplePreparedStatementSetter"  />
     < bean  id = "allowSkipProcessor"  class = "com.lyx.batch.AllowSkipProcessor"  />
     < bean  id = "addDescPeopleWriter"  class = "com.lyx.batch.AddDescPeopleWriter"  />
 
     <!--tomcat jdbc pool数据源配置 -->
     < bean  id = "dataSource"  class = "org.apache.tomcat.jdbc.pool.DataSource"
         destroy-method = "close" >
         < property  name = "poolProperties" >
             < bean  class = "org.apache.tomcat.jdbc.pool.PoolProperties" >
                 < property  name = "driverClassName"  value = "com.mysql.jdbc.Driver"  />
                 < property  name = "url"  value = "jdbc:mysql://localhost:3306/test"  />
                 < property  name = "username"  value = "root"  />
                 < property  name = "password"  value = "034039"  />
             </ bean >
         </ property >
     </ bean >
 
     <!-- spring batch 配置jobRepository -->
     < batch:job-repository  id = "jobRepository"
         data-source = "dataSource"  transaction-manager = "transactionManager"
         isolation-level-for-create = "REPEATABLE_READ"  table-prefix = "BATCH_"
         max-varchar-length = "1000"  />
     <!-- spring的事务管理器 -->
     < bean  id = "transactionManager"
         class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
         < property  name = "dataSource"  ref = "dataSource"  />
     </ bean >
     <!-- batch luncher -->
     < bean  id = "jobLauncher"
         class = "org.springframework.batch.core.launch.support.SimpleJobLauncher" >
         < property  name = "jobRepository"  ref = "jobRepository"  />
     </ bean >
</ beans >


其中最主要的就是:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- add people desc job begin -->
< batch:job  id = "addPeopleDescJob" >
     < batch:step  id = "addDescStep"  parent = "abstractStep" >
         < batch:tasklet >
             < batch:chunk  reader = "peopleAddDescReader"  processor = "allowSkipProcessor"
                 writer = "addDescPeopleWriter"  commit-interval = "2"  skip-limit = "10" >
                 < batch:skippable-exception-classes >
                     <!--batch:include配置允许发生的异常 -->
                     < batch:include  class = "com.lyx.batch.InvalidDataException"  />
                 </ batch:skippable-exception-classes >
             </ batch:chunk >
         </ batch:tasklet >
     </ batch:step >
     <!-- 在job的运行期间,可以监视job -->
     < batch:listeners >
         < batch:listener  ref = "sampleListener"  />
     </ batch:listeners >
</ batch:job >
<!-- add people desc job end -->
< bean  id = "sampleListener"  class = "com.lyx.batch3.SampleJobExecutionListener"  />

通过实现 JobExecutionListener接口捕捉job 运行事件:

SampleJobExecutionListener.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package  com.lyx.batch3;
 
import  org.springframework.batch.core.BatchStatus;
import  org.springframework.batch.core.JobExecution;
import  org.springframework.batch.core.JobExecutionListener;
 
public  class  SampleJobExecutionListener  implements  JobExecutionListener {
 
     public  void  beforeJob(JobExecution jobExecution) {
         System.out.println( "job start........." );
 
     }
 
     public  void  afterJob(JobExecution jobExecution) {
         if  (jobExecution.getStatus() == BatchStatus.COMPLETED) {
             // job success
 
             System.out.println( "job success........." );
         else  if  (jobExecution.getStatus() == BatchStatus.FAILED) {
             // job failure
             System.out.println( "job failure........." );
         }
     }
 
}

需要注意的是 afterJob 方法不管job运行成功还是失败都会执行。


运行AppMain11.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package  com.lyx.batch;
 
import  org.springframework.batch.core.ExitStatus;
import  org.springframework.batch.core.Job;
import  org.springframework.batch.core.JobExecution;
import  org.springframework.batch.core.JobParametersBuilder;
import  org.springframework.batch.core.JobParametersInvalidException;
import  org.springframework.batch.core.launch.JobLauncher;
import  org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import  org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import  org.springframework.batch.core.repository.JobRestartException;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
  * job execution listener
 
  * @author Lenovo
  *
  */
public  class  AppMain11 {
     public  static  void  main(String[] args)
             throws  JobExecutionAlreadyRunningException, JobRestartException,
             JobInstanceAlreadyCompleteException, JobParametersInvalidException {
 
         long  startTime = System.currentTimeMillis();  // 获取开始时间
 
         @SuppressWarnings ( "resource" )
         ApplicationContext context =  new  ClassPathXmlApplicationContext(
                 new  String[] {  "classpath:spring-batch-exception-listener.xml"  });
         JobParametersBuilder jobParametersBuilder =  new  JobParametersBuilder();
         Job job = (Job) context.getBean( "addPeopleDescJob" );
         JobLauncher launcher = (JobLauncher) context.getBean( "jobLauncher" );
         JobExecution result = launcher.run(job,
                 jobParametersBuilder.toJobParameters());
         ExitStatus es = result.getExitStatus();
         if  (es.getExitCode().equals(ExitStatus.COMPLETED.getExitCode())) {
             System.out.println( "任务正常完成" );
         else  {
             System.out.println( "任务失败,exitCode="  + es.getExitCode());
         }
 
         long  endTime = System.currentTimeMillis();  // 获取结束时间
         System.out.println( "程序运行时间: "  + (endTime - startTime) +  "ms" );
     }
}


运行结果:

信息: Job: [FlowJob: [name=addPeopleDescJob]] launched with the following parameters: [{}]

job start.........

十一月 19, 2014 12:27:39 下午 org.springframework.batch.core.job.SimpleStepHandler handleStep

信息: Executing step: [addDescStep]

.............................................

job success.........

十一月 19, 2014 12:27:43 下午 org.springframework.batch.core.launch.support.SimpleJobLauncher run

信息: Job: [FlowJob: [name=addPeopleDescJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]

任务正常完成

程序运行时间: 6898ms

==================END==================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值