tasklet和chunk的区别

3 篇文章 0 订阅
3 篇文章 0 订阅

在spring batch 的步骤中,具体执行业务逻辑的代码放在tasklet中。

spring batch 提供了两种方式:

1、使用chunk实现标准的读、处理、写三种操作;

2、实现 tasklet 接口,并实现其 execute 方法。

一、chunk

先看看如何使用chunk来定义一个任务和步骤,代码如下:

<!-- 定义任务和步骤 -->
    <batch:job id="XXXJob" restartable="true" job-repository="jobRepository">
        <batch:step id="XXXStep">
            <batch:tasklet transaction-manager="transactionManager" >
                <batch:chunk reader="XXXReader"
                             writer="XXXWriter"
                             processor="XXXProcessor"
                             commit-interval="10">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

 

Chunk 典型地提供了标准的read、process、write三种操作,而且还有事务提交间隔、重试策略等。

Step、tasklet、chunk这三者的关系图如下:

从代码上也可看出,Chunk是定义在Tasklet里面的。

 

二、Tasklet

Tasklet定义一个步骤的示例,可直接参考官网给出来的代码。

1、首先定义一个实现Tasklet的类:

public class FileDeletingTasklet implements Tasklet, InitializingBean {
    private Resource directory;
    
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        File dir = directory.getFile();
        Assert.state(dir.isDirectory());
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            boolean deleted = files[i].delete();
            if (!deleted) {
                throw new UnexpectedJobExecutionException("Could not delete file " + files[i].getPath());
            }
        }
        return RepeatStatus.FINISHED;
     }
     
    public void setDirectoryResource(Resource directory) {
        this.directory = directory;
    }
        
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(directory, "directory must be set");
    }
}

2、XML配置:

<job id="taskletJob">
    <step id="deleteFilesInDir">
        <tasklet ref="fileDeletingTasklet"/>
    </step>
</job>

<beans:bean id="fileDeletingTasklet" class="org.springframework.batch.sample.tasklet.FileDeletingTasklet">
    <beans:property name="directoryResource">
        <beans:bean id="directory" class="org.springframework.core.io.FileSystemResource">
        <beans:constructor-arg value="target/test-outputs/test-dir" />
        </beans:bean>
    </beans:property>
</beans:bean>

三、两者区别

《Spring batch 批处理框架》一书中,提到Tasklet时如下描述:

 

提到Chunk的描述如下:

但这并没提到这两者的区别。

找到官方文档,在介绍Tasklet中有这么一段话:

Chunk-oriented processing is not the only way to process in a Step. What if a Step must consist of a

simple stored procedure call? You could implement the call as an ItemReader and return null after

the procedure finishes. However, doing so is a bit unnatural, since there would need to be a no-op

ItemWriter. Spring Batch provides the TaskletStep for this scenario.

 

Tasklet is a simple interface that has one method, execute, which is called repeatedly by the

TaskletStep until it either returns RepeatStatus.FINISHED or throws an exception to signal a failure.

Each call to a Tasklet is wrapped in a transaction. Tasklet implementors might call a stored

procedure, a script, or a simple SQL update statement.

这两段话,第一段描述了Tasklet的使用场景,第二段介绍Tasklet的一些使用细节。第一段话的翻译大致如下:

块处理不是处理步骤的唯一方法。 如果一个步骤必须包含一个简单的存储过程调用怎么办? 您可以将调用实现为ItemReader,并在过程完成后返回null。 但是,这样做有点不自然,因为将需要一个无任何操作的ItemWriter。 因此,Spring Batch为此场景提供了TaskletStep。 

看到这里,我一开始也没懂,但看了后面官网给的例子,也就大致明白了,官网在给Tasklet例子前有这么一段描述 :

Many batch jobs contain steps that must be done before the main processing begins in order to set

up various resources or after processing has completed to cleanup those resources. In the case of a

job that works heavily with files, it is often necessary to delete certain files locally after they have

been uploaded successfully to another location.

看了例子,发现这例子就是在一个Tasklet的execute方法中,对文件进行删除,没有对文件内容进行读、写操作 。

 

因此可以认为:

Tasklet 适用于该 Step 操作不需要读操作,或不需要写操作,或两者都不需要。

而Chunk则适用于典型的Read、Process、Write 操作。

 

官网的介绍中提到,如果你的步骤包含一个简单的存储过程调用(只存,不需要写),那就可以用Tasklet。当然,你也可以用Chunk,但这时,你的ItemWritter就是一个空实现,看着不自然。

而官网的Tasklet例子只对文件进行删除,不需要读、写文件的内容,因此用Tasklet也就非常合适了。

参考:

spring batch 官网文档:https://docs.spring.io/spring-batch/docs/4.2.x/reference/pdf/spring-batch-reference.pdf

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
好的,以下是一个基于 Spring Batch 的 Job,其中包含两个 Step。每个 Step 都有自己的 ItemReader、ItemProcessor 和 ItemWriter。 首先,我们需要在 Spring 配置文件中定义 Job 和 Step 的 Bean。 ```xml <bean id="job" class="org.springframework.batch.core.job.SimpleJob"> <property name="jobRepository" ref="jobRepository"/> <property name="name" value="myJob"/> <property name="restartable" value="true"/> <property name="startLimit" value="3"/> <property name="incrementer"> <bean class="org.springframework.batch.core.launch.support.RunIdIncrementer"/> </property> <property name="steps"> <list> <ref bean="step1"/> <ref bean="step2"/> </list> </property> </bean> <bean id="step1" class="org.springframework.batch.core.step.tasklet.TaskletStep"> <property name="jobRepository" ref="jobRepository"/> <property name="transactionManager" ref="transactionManager"/> <property name="tasklet"> <bean class="com.example.Step1Tasklet"/> </property> <property name="chunkSize" value="100"/> <property name="commitInterval" value="10"/> </bean> <bean id="step2" class="org.springframework.batch.core.step.tasklet.TaskletStep"> <property name="jobRepository" ref="jobRepository"/> <property name="transactionManager" ref="transactionManager"/> <property name="tasklet"> <bean class="com.example.Step2Tasklet"/> </property> <property name="chunkSize" value="100"/> <property name="commitInterval" value="10"/> </bean> ``` 接下来,我们需要编写 Step 的 Tasklet 类和 ItemReader、ItemProcessor、ItemWriter 类。 ```java public class Step1Tasklet implements Tasklet { private ItemReader<MyInput> reader; private ItemProcessor<MyInput, MyOutput> processor; private ItemWriter<MyOutput> writer; // 构造函数注入 Reader、Processor、Writer public Step1Tasklet(ItemReader<MyInput> reader, ItemProcessor<MyInput, MyOutput> processor, ItemWriter<MyOutput> writer) { this.reader = reader; this.processor = processor; this.writer = writer; } @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { List<MyOutput> outputs = new ArrayList<>(); MyInput input; // 从 Reader 中读取数据,逐条进行处理 while ((input = reader.read()) != null) { MyOutput output = processor.process(input); outputs.add(output); } // 将处理结果写入到 Writer 中 writer.write(outputs); return RepeatStatus.FINISHED; } } public class Step2Tasklet implements Tasklet { private ItemReader<MyOutput> reader; private ItemProcessor<MyOutput, MyOutput> processor; private ItemWriter<MyOutput> writer; // 构造函数注入 Reader、Processor、Writer public Step2Tasklet(ItemReader<MyOutput> reader, ItemProcessor<MyOutput, MyOutput> processor, ItemWriter<MyOutput> writer) { this.reader = reader; this.processor = processor; this.writer = writer; } @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { List<MyOutput> outputs = new ArrayList<>(); MyOutput input; // 从 Reader 中读取数据,逐条进行处理 while ((input = reader.read()) != null) { MyOutput output = processor.process(input); outputs.add(output); } // 将处理结果写入到 Writer 中 writer.write(outputs); return RepeatStatus.FINISHED; } } public class MyInput { // 输入数据类 } public class MyOutput { // 输出数据类 } public class MyInputItemReader implements ItemReader<MyInput> { // 输入数据读取器 } public class MyOutputItemReader implements ItemReader<MyOutput> { // 输出数据读取器 } public class MyItemProcessor implements ItemProcessor<MyInput, MyOutput> { // 数据处理器 } public class MyItemWriter implements ItemWriter<MyOutput> { // 数据写入器 } ``` 最后,我们需要在 Spring 配置文件中定义 Reader、Processor、Writer 的 Bean。 ```xml <bean id="myInputReader" class="com.example.MyInputItemReader"/> <bean id="myOutputReader" class="com.example.MyOutputItemReader"/> <bean id="myProcessor" class="com.example.MyItemProcessor"/> <bean id="myWriter" class="com.example.MyItemWriter"/> ``` 这样,我们就完成了一个基于 Spring Batch 的 Job,其中包含两个 Step。每个 Step 都有自己的 ItemReader、ItemProcessor 和 ItemWriter,可以适用于多个 Step 下的数据处理场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值