Spring Batch_Intercepting Job Execution

Spring Batch_Intercepting Job Execution_配置JobExecutionListener

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

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

如下配置:

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

其中最主要的就是:

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

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

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

时间: 2024-09-18 14:01:23

Spring Batch_Intercepting Job Execution的相关文章

Spring Batch_Intercepting Step Execution

Spring Batch_Intercepting Step Execution_配置SkipListener 关于配置skip:http://my.oschina.net/xinxingegeya/blog/346244 先看一下StepListener.java 接口的继承关系图: StepExecutionListener StepExecutionListener represents the most generic listener for Step execution. It al

Spring AspectJ的Execution表达式-备忘笔记

Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式  execution (* com.sample.service.impl..*.*(..)) execution()是最常用的切点函数,其语法如下所示: 整个表达式可以分为五个部分: 1.execution(): 表达式主体. 2.第一个*号:表示返回类型,*号表示所有的类型. 3.包名:表示需要拦截的包名,后面的两个

spring AspectJ的Execution表达式

在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execution(* com.sample.service.impl..*.*(..)) execution()是最常用的切点函数,其语法如下所示: 整个表达式可以分为五个部分: 1.execution(): 表达式主体. 2.第一个*号:表示返回类型,*号表示所有的类型. 3.包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,

spring AspectJ的Execution表达式说明

Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execution(* com.myself.service.impl..*.*(..)) execution()是最常用的切点函数,其语法如下所示: 整个表达式可以分为五个部分: 1.execution(): 表达式主体. 2.第一个*号:表示返回类型,*号表示所有的类型. 3.包名:表示需要拦截的包名,后面的两个句点

Spring Aop中execution的语法

参考地址:https://blog.csdn.net/zz210891470/article/details/54175107 execution(* com.sample.service.impl..*.*(..)) 解释如下: 符号 含义 execution() 表达式的主体: 第一个”*“符号 表示返回值的类型任意: com.sample.service.impl AOP所切的服务的包名,即,我们的业务部分 包名后面的”..“ 表示当前包及子包 第二个”*“ 表示类名,*即所有类.此处可以

Spring框架之Spring AOP

一.基于注解管理的AOP 1.Spring配置文件 <!-- 配置自动扫描包,自动扫描Bean组件,切面类 --> <context:component-scan base-package="com.zhoujian.spring.anno,com.zhoujian.spring.test"> <!-- <context:include-filter type="annotation" expression="org.a

【Spring四】AOP之XML配置

AOP:Aspect Oriented  Programming 面向切面编程 面向切面编程的核心是动态代理设计模式.请先參见动态代理设计模式笔记. 以Hibernate保存一个对象到数据库为例,因为保存数据时须要开启事务,利用面向切面编程思想,将事务的处理分离出来.当作一个切面来处理. jdk的动态代理的缺点: 1.在拦截器中,切入点的推断是很复杂的 2.尽管实现了切面与目标类的松耦合,可是在拦截器中还得实现结合过程 一.springAOP的原理: 目标类:在目标类的方法调用的前后,我们须要增

Spring Boot POM 详解

正如这幅图所展示的那样,在Spring IO Framework体系中,Spring Boot处在Execution layer,来看看官方对这层的解释: The Spring IO Execution layer provides domain-specific runtimes (DSRs) for applications built on the IO Foundation modules. A DSR may run standalone without requiring deplo

SpringAOP和Spring事物管理

Spring AOP : Pointcut表达式: designators-指示器 wildcards-通配符 operators-操作符 wildcards: * -- 匹配任意数量的字符 + -- 匹配制定类及其子类 ..-- 一般用于匹配任意数的子包或参数 operator: && || ! Wildcards(通配符) * 匹配任意数量的字符 + 匹配指定类及其子类 .. 一般用于匹配任意数的子包或参数 Pointcut :切面表达式 designators:指示器,描述通过什么方