第四章 配置作业Job

4.1 基本配置

Job的配置有3个必须的属性。name,jobRepository,steps。一个简单的Job配置例如以下:

  1. <job id="footballJob">
  2. <step id="playerload" parent="s1" next="gameLoad"/>
  3. <step id="gameLoad" parent="s2" next="playerSummarization"/>
  4. <step id="playerSummarization" parent="s3"/>
  5. </job>

jobRepository默认引用名称为jobRepository的bean,当然也能够显式地配置:

  1. <job id="footballJob" job-repository="specialRepository">
  2. <step id="playerload" parent="s1" next="gameLoad"/>
  3. <step id="gameLoad" parent="s3" next="playerSummarization"/>
  4. <step id="playerSummarization" parent="s3"/>
  5. </job>
4.1.1 Restartable属性

该属性定义Job能否够被重新启动,默觉得true,在JobExecution运行失败后,能够创建还有一个JobExecution来继续上次的运行。

可是假设该属性设为false。又一次运行该JobInstance将抛出异常。

  1. <job id="footballJob" restartable="false">
  2. ...
  3. </job>
4.1.2 拦截Job运行

Spring Batch在Job的生命周期中提供了一些钩子方法,可这些钩子方法通过Listener的形式提供。JobListener的接口定义例如以下:

  1. public interface JobExecutionListener {
  2. void beforeJob(JobExecution jobExecution);
  3. void afterJob(JobExecution jobExecution);
  4. }

通过实现JobExecutionListener接口并配置给Job,能够在Job运行前后运行特定的逻辑。

比如在运行结束之后。假设失败,发送邮件通知管理人员等。

  1. <job id="footballJob">
  2. <step id="playerload" parent="s1" next="gameLoad"/>
  3. <step id="gameLoad" parent="s2" next="playerSummarization"/>
  4. <step id="playerSummarization" parent="s3"/>
  5. <listeners>
  6. <listener ref="sampleListener"/>
  7. </listeners>
  8. </job>

须要注意的是。不管Job是否成功运行,afterJob方法都会运行。Job是否运行成功,能够从JobExecution中获取。

  1. public void afterJob(JobExecution jobExecution){
  2. if( jobExecution.getStatus() == BatchStatus.COMPLETED ){
  3. //job success
  4. }
  5. else if(jobExecution.getStatus() == BatchStatus.FAILED){
  6. //job failure
  7. }
  8. }

Listener的运行顺序:

beforeJob与配置的顺序一样,afterJob与配置的顺序相反。

Listener异常:

Listener的运行过程中假设抛出异常,将导致Job无法继续完毕,终于状态为FAILED.因此要合理控制Listener异常对业务的影响。

注解支持:

假设不想使用侵入性强的Listener接口,能够使用@BeforeJob和@AfterJob两个注解声明。

4.1.3 Job抽象与继承

通用的Job配置能够抽取出来,作为抽象的Job存在,抽象的Job不同意被实例化:

  1. <job id="baseJob" abstract="true">
  2. <listeners>
  3. <listener ref="listenerOne"/>
  4. <listeners>
  5. </job>

子Job能够通过继续共用这些配置(当然。也能够继承非抽象的Job)。

  1. <job id="job1" parent="baseJob">
  2. <step id="step1" parent="standaloneStep"/>
  3. <listeners merge="true">
  4. <listener ref="listenerTwo"/>
  5. <listeners>
  6. </job>

当中的merge=”true”表示合并父job和子job的配置,也就是两个Listener都生效。同常规的Spring配置。

4.1.4 Job參数验证

JobParameterValidator组件用于验证JobParameter。

通过以下配置为job配置验证器:

  1. <job id="job1" parent="baseJob3">
  2. <step id="step1" parent="standaloneStep"/>
  3. <validator ref="paremetersValidator"/>
  4. </job>
4.1.4 属性的Late Binding

在Spring中。能够把Bean配置用到的属性值通过PropertiesPlaceHolderConfiguer把属性从配置中分离出来独立管理,理论上来说,在配置Job的时候也能够使用同样的方式。可是Spring Batch提供了在运行时配置參数值的能力:

  1. <bean:property name="filePath" value="#{jobParameters['filePath']}" />

在启动Job时:

  1. launcher.executeJob("job.xml" , "footjob",
  2. new JobParametersBuilder().addDate("day", new Date()))
  3. .addString("filePath", "/opt/data/test.xml"));

4.2 配置JobRepository

JobRepository为任务框架中的各个组件对象提供CRUD操作,比如JobExecution,StepExecution。

一个配置样例例如以下:

  1. <job-repository id="jobRepository"
  2. data-source="dataSource"
  3. transaction-manager="transactionManager"
  4. isolation-level-for-create="SERIALIZABLE"
  5. table-prefix="BATCH_"
  6. max-varchar-length="1000"/>
4.2.1 事务配置

JobRepository的操作须要事务来保证其完整性以及正确性,这些元数据的完整性对框架来说非常重要。假设没有事务支持。框架的行为将无法正确定义。

create*方法的事务隔离级别单独定义,为了保证同一个JobInstance不会被同一时候运行两次,默认的隔离级别为SERIALIZABLE。能够被改动:

  1. <job-repository id="jobRepository"
  2. isolation-level-for-create="REPEATABLE_READ" />

假设没有使用Batch命名空间或者没有使用Factory Bean,则须要显示配置事务AOP:

  1. <aop:config>
  2. <aop:advisor
  3. pointcut="execution(* org.springframework.batch.core..*Repository+.*(..))"/>
  4. <advice-ref="txAdvice" />
  5. </aop:config>
  6. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  7. <tx:attributes>
  8. <tx:method name="*" />
  9. </tx:attributes>
  10. </tx:advice>
4.2.2 表名前缀

默认情况下,Spring Batch须要的表以BATCH作为前缀,只是能够自己定义:

  1. <job-repository id="jobRepository"
  2. table-prefix="e_batch" />

表前缀能够改动,可是表名和表的列不能被改动。

4.2.3 特殊的Repository

測试环境中。内存级别的数据库十分方便:

  1. <bean id="jobRepository"
  2. class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
  3. <property name="transactionManager" ref="transactionManager"/>
  4. </bean>

假设使用的数据库类型不在SpringBatch的支持中,能够通过JobRepositoryFactoryBean自己定义。

4.3 配置JobLauncher

默认提供了一个简单的Launcher:

  1. <bean id="jobLauncher"
  2. class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  3. <property name="jobRepository" ref="jobRepository" />
  4. </bean>

JobLauncher的时序图例如以下:

假设启动的请求来自HTTP,那么等待整个Job完毕再返回不是一个好方法。此时须要异步启动Job,时序图例如以下:

对应的Launcher配置例如以下:

  1. <bean id="jobLauncher"
  2. class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  3. <property name="jobRepository" ref="jobRepository" />
  4. <property name="taskExecutor">
  5. <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
  6. </property>
  7. </bean>

4.4 运行Job

有多种方式能够启动一个Job。可是核心都是通过JobLauncher来实现。

1. 命令行运行

主要通过CommandLineJobRunner类完毕




2. 从Web容器中运行

通过Http请求启动任务非经常见。时序图例如以下:

Controller能够是常规的Spring MVC Controller:

  1. @Controller
  2. public class JobLauncherController {
  3. @Autowired
  4. JobLauncher jobLauncher;
  5. @Autowired
  6. Job job;
  7. @RequestMapping("/jobLauncher.html")
  8. public void handle() throws Exception{
  9. jobLauncher.run(job, new JobParameters());
  10. }
  11. }

3. 使用调度框架运行

能够与其它调度框架一起使用,比如使用Spring的轻量级调用框架Spring Scheduler或者Quartz

4.5 元数据的高级使用方法

除了通过JobRepository对元数据进行CRUD操作外,Spring batch还提供另外的接口用于訪问元数据。

包含: JobExplorer JobOperator。

总体结构例如以下:

4.5.1 JobExplorer

该组件提供了仅仅读的查询操作,是JobRepository的仅仅读版本号,接口定义例如以下:

  1. public interface JobExplorer {
  2. List<JobInstance> getJobInstances(String jobName, int start, int count);
  3. JobExecution getJobExecution(Long executionId);
  4. StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId);
  5. JobInstance getJobInstance(Long instanceId);
  6. List<JobExecution> getJobExecutions(JobInstance jobInstance);
  7. Set<JobExecution> findRunningJobExecutions(String jobName);
  8. }

配置一个Bean例如以下:

  1. <bean id="jobExplorer" class="org.spr...JobExplorerFactoryBean"
  2. p:dataSource-ref="dataSource" />

假设须要制定表名前缀:

  1. <bean id="jobExplorer" class="org.spr...JobExplorerFactoryBean"
  2. p:dataSource-ref="dataSource" p:tablePrefix="BATCH_" />
4.5.2 JobOperator

JobOperator集成了非常多接口定义,提供了综合的操作方法。定义例如以下:

  1. public interface JobOperator {
  2. List<Long> getExecutions(long instanceId) throws NoSuchJobInstanceException;
  3. List<Long> getJobInstances(String jobName, int start, int count)
  4. throws NoSuchJobException;
  5. Set<Long> getRunningExecutions(String jobName) throws NoSuchJobException;
  6. String getParameters(long executionId) throws NoSuchJobExecutionException;
  7. Long start(String jobName, String parameters)
  8. throws NoSuchJobException, JobInstanceAlreadyExistsException;
  9. Long restart(long executionId)
  10. throws JobInstanceAlreadyCompleteException, NoSuchJobExecutionException,
  11. NoSuchJobException, JobRestartException;
  12. Long startNextInstance(String jobName)
  13. throws NoSuchJobException, JobParametersNotFoundException, JobRestartException,
  14. JobExecutionAlreadyRunningException, JobInstanceAlreadyCompleteException;
  15. boolean stop(long executionId)
  16. throws NoSuchJobExecutionException, JobExecutionNotRunningException;
  17. String getSummary(long executionId) throws NoSuchJobExecutionException;
  18. Map<Long, String> getStepExecutionSummaries(long executionId)
  19. throws NoSuchJobExecutionException;
  20. Set<String> getJobNames();
  21. }

配置:

  1. <bean id="jobOperator" class="org.spr...SimpleJobOperator">
  2. <property name="jobExplorer">
  3. <bean class="org.spr...JobExplorerFactoryBean">
  4. <property name="dataSource" ref="dataSource" />
  5. </bean>
  6. </property>
  7. <property name="jobRepository" ref="jobRepository" />
  8. <property name="jobRegistry" ref="jobRegistry" />
  9. <property name="jobLauncher" ref="jobLauncher" />
  10. </bean>

当中的startNextInstance方法将使用当前Job的JobParameter。经过JobParametersIncrementer处理之后的參数启动一个JobInstance。

  1. public interface JobParametersIncrementer {
  2. JobParameters getNext(JobParameters parameters);
  3. }

以下是一个简单实现:

  1. public class SampleIncrementer implements JobParametersIncrementer {
  2. public JobParameters getNext(JobParameters parameters) {
  3. if (parameters==null || parameters.isEmpty()) {
  4. return new JobParametersBuilder().addLong("run.id", 1L).toJobParameters();
  5. }
  6. long id = parameters.getLong("run.id",1L) + 1;
  7. return new JobParametersBuilder().addLong("run.id", id).toJobParameters();
  8. }
  9. }

为job配置incrementer:

  1. <job id="footballJob" incrementer="sampleIncrementer">
  2. ...
  3. </job>

在每天处理一次的批处理中,Incrementer的实现可能是按日期递增。

Spring Batch(4): Job具体解释的更多相关文章

  1. Springboot集成Spring Batch

    Spring官网 (https://spring.io/projects/spring-batch#overview)对Spring  Batch的解释: 一个轻量级的.全面的批处理框架,用于开发对企 ...

  2. spring batch批处理框架学习

    内如主要来自以下链接: http://www.importnew.com/26177.html http://www.infoq.com/cn/articles/analysis-of-large-d ...

  3. Spring Batch 批处理框架介绍

    前言 在大型的企业应用中,或多或少都会存在大量的任务需要处理,如邮件批量通知所有将要过期的会员,日终更新订单信息等.而在批量处理任务的过程中,又需要注意很多细节,如任务异常.性能瓶颈等等.那么,使用一 ...

  4. Spring batch学习 (1)

    Spring Batch 批处理框架 埃森哲和Spring Source研发 主要解决批处理数据的问题,包含并行处理,事务处理机制等.具有健壮性 可扩展,和自带的监控功能,并且支持断点和重发.让程序员 ...

  5. 思维导图与Spring Batch

    最近在学画图,又在复习Spring Batch.不解释,直接上图. 第三章,用XMind画的. 第五章,用iMindMap画的.

  6. Spring Boot整合Spring Batch

    引言 Spring Batch是处理大量数据操作的一个框架,主要用来读取大量数据,然后进行一定的处理后输出指定的形式.比如我们可以将csv文件中的数据(数据量几百万甚至几千万都是没问题的)批处理插入保 ...

  7. Spring Batch在大型企业中的最佳实践

    在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...

  8. spring batch资料收集

    spring batch官网 Spring Batch在大型企业中的最佳实践 一篇文章全面解析大数据批处理框架Spring Batch Spring Batch系列总括

  9. Spring Batch学习笔记三:JobRepository

    此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch Job在运行时有很多元数据,这些元数据一般会被保存在内存或者数据库中,由于Spring Batch在默认配置是使用H ...

随机推荐

  1. Sort a linked list in O(n log n) time using constant space complexity.

    因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想. 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二: 2)递归地对左半部分进行归并排序: 3)递归地对右半部分进行归并排 ...

  2. A. Test for Job

    A. Test for Job Time Limit: 5000ms Case Time Limit: 5000ms Memory Limit: 65536KB   64-bit integer IO ...

  3. Dialog共通写法(两个button)

    package jp.co.hyakujushibank.view import android.app.Dialogimport android.content.Contextimport andr ...

  4. hihoCoder 1367 等式填空

    明确题意 等号左边是由'+'和'?'组成的算式,其中处于某个整数(即便这个整数只有一位)首位的'?'可以填入1-9中的某个数字,其余'?'可以填入0-9中的某个数字. SOURCE 这里未明确等号左边 ...

  5. 刷题总结——shortest(ssoi)

    题目: 题目背景 SOURCE:NOIP2015-SHY-3 题目描述 给定一张 n 个点的有向带权完全图,和一个数组 a[] ,请按顺序删除数组中的点,请求出在删除点 a[i] 以前,所有未删除点对 ...

  6. 常州模拟赛d2t1 小X的质数

    题目背景 小 X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的 情感.小 X 认为,质数是一切自然数起源的地方. 题目描述 在小 X 的认知里,质数是除了本身和 1 以外,没有其他因 ...

  7. P1279 字串距离 (动态规划)

    题目描述 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字符串“abcb□cd”,“□a□bcbcd□”和“abcb□cd□”都是X ...

  8. eclipse 搭建ruby环境

    第一步:获取RDT,http://sourceforge.net/projects/rubyeclipse/files/ 解压该文件,获得features和plugins两个文件夹,将这两个文件夹分别 ...

  9. Yii 之控制器创建使用

    在根目录下的controllers目录下创建控制器HelloController.php: <?php namespace app\controllers; use yii\web\Contro ...

  10. Redis数据结构之压缩列表

    压缩列表是Redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构.一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值. 一.压缩列表结构1. 压缩列 ...