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==================