SpringBatch的两种实现方式: Tasklet 和 Chunk

news/2024/10/21 3:41:54/

直接上代码

■ 共通部分:

1. 代码结构

 

 2. pom.xml

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId></dependency>

3. framework/BatchAnnotation.java

package roy.springbatch.framework;import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;import java.lang.annotation.*;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@Import({SimpleBatchConfiguration.class})
@EnableBatchProcessing
@ComponentScan
@ComponentScans({@ComponentScan("roy.springbatch.framework")})
@PropertySource(value = "classpath:config/jdbc-dev.properties")
public @interface BatchAnnotation {
}

4. framework/BaseModule.java

package roy.springbatch.framework;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;import java.util.HashMap;
import java.util.Map;public abstract class BaseModule implements CommandLineRunner {private static final Logger log = LoggerFactory.getLogger(BaseModule.class);public static void run(Class<? extends BaseModule> module, String batchName, String[] args)throws Exception {SpringApplication app = new SpringApplication(module);Map<String, Object> param = retriveArgs(batchName, args);app.setDefaultProperties(param);app.run(args);}private static Map<String, Object> retriveArgs(String batchName, String[] args){Map<String, Object> param = new HashMap<>();param.put("argsLength", args.length);if (args.length>0){param.put("targetDate", args[0]);}return param;}@Overridepublic void run(String... args) throws Exception{if (null != args){for(String arg : args){log.info("execute module with argument : " + arg);}}}
}

5. framework/BaseWriter.java

package roy.springbatch.framework;import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;public abstract class BaseWriter<T> implements ItemWriter<T> {protected StepExecution stepExecution;@BeforeSteppublic void saveStepExecution(StepExecution stepExecution){this.stepExecution = stepExecution;}@Overridepublic void write(List<? extends T> items) throws Exception {JobParameters params = stepExecution.getJobParameters();ExecutionContext stepContext = stepExecution.getExecutionContext();for(T item : items){doWrite(item, params, stepContext);}}public abstract void doWrite(T item, JobParameters params, ExecutionContext stepContext) throws Exception;
}

一. Tasklet

1. batTasklet/BatTasklet.java

package roy.springbatch.batTasklet;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import roy.springbatch.framework.BaseModule;
import roy.springbatch.framework.BatchAnnotation;@BatchAnnotation
public class BatTasklet extends BaseModule {private static final Logger log = LoggerFactory.getLogger(BatTasklet.class);private static final String MODULE_NAME = "BATCHTASKLET";public static void main(String[] args) {try {run(BatTasklet.class, MODULE_NAME, args);} catch (Exception e) {log.error(MODULE_NAME + " failed.");System.exit(1);}}
}

2. batTasklet/BatTaskletConfiguration.java

package roy.springbatch.batTasklet;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import roy.springbatch.framework.BaseModule;@Configuration
@EnableBatchProcessing
public class BatTaskletConfiguration extends BaseModule {private static final Logger log = LoggerFactory.getLogger(BatTaskletConfiguration.class);@Autowiredprivate JobLauncher jobLauncher;@Autowiredprivate JobBuilderFactory jobBuilderFactory;@Autowiredprivate StepBuilderFactory stepBuilderFactory;@Autowiredprivate Tasklet tasklet1;@Autowiredprivate Tasklet tasklet2;@Beanpublic Step step1(){return stepBuilderFactory.get("step1").allowStartIfComplete(true).tasklet(tasklet1).build();}@Beanpublic Step step2(){return stepBuilderFactory.get("step2").allowStartIfComplete(true).tasklet(tasklet2).build();}@Beanpublic Job job(){return jobBuilderFactory.get("step-tasklet-job").incrementer(new RunIdIncrementer()).start(step1()).next(step2()).build();}}

3. batTasklet/Task1.java (具体想要做的事情写在Task里面)

package roy.springbatch.batTasklet;import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class Task1 {@Beanpublic Tasklet tasklet1(){return new Tasklet() {@Overridepublic RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {System.out.println("--->Tasklet 1 Execute:" + System.currentTimeMillis());return RepeatStatus.FINISHED;}};}
}

4. batTasklet/Task2.java

package roy.springbatch.batTasklet;import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class Task2 {@Beanpublic Tasklet tasklet2(){return new Tasklet() {@Overridepublic RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {System.out.println("--->Tasklet 2 Execute:" + System.currentTimeMillis());return RepeatStatus.FINISHED;}};}
}

5. 测试:

二. Chunk

1. batChunk/listener/BatChunkListener.java

package roy.springbatch.batChunk.listener;import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.stereotype.Component;@Component
public class BatChunkListener extends JobExecutionListenerSupport {@Overridepublic void beforeJob(JobExecution jobExecution){System.out.println("--->BeforeJob Execute");}@Overridepublic void afterJob(JobExecution jobExecution){System.out.println("--->AfterJob Execute");}
}

2. batChunk/reader/BatChunkReader.java

package roy.springbatch.batChunk.reader;import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;import java.util.HashMap;
import java.util.Map;public class BatChunkReader implements ItemReader<Map<String, String>> {private int stepCount = 0;private Map<String, String> listMap = new HashMap<>();@Overridepublic Map<String, String> read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {if(stepCount<3){stepCount++;System.out.println("--->Reader Execute: read from DB");listMap.put("A1", "1");listMap.put("A2", "2");listMap.put("A3", "3");return listMap;}else {return null;}}
}

3. batChunk/writer/BatChunkWriter.java

package roy.springbatch.batChunk.writer;import org.springframework.batch.core.JobParameters;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import roy.springbatch.framework.BaseWriter;import java.util.Map;@Component
@Scope("prototype")
public class BatChunkWriter extends BaseWriter<Map<String, String>> {@Overridepublic void doWrite(Map<String, String> map, JobParameters params,ExecutionContext stepContext) throws Exception {System.out.println("--->Writer Execute: write to DB:" + map.toString());}
}

4. batChunk/BatChunk.java

package roy.springbatch.batChunk;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import roy.springbatch.framework.BaseModule;
import roy.springbatch.framework.BatchAnnotation;@BatchAnnotation
public class BatChunk extends BaseModule {private static final Logger log = LoggerFactory.getLogger(BatChunk.class);private static final String MODULE_NAME = "BATCHCHUNK";public static void main(String[] args) {try {run(BatChunk.class, MODULE_NAME, args);} catch (Exception e) {log.error(MODULE_NAME + " failed.");System.exit(1);}}
}

5. batChunk/BatChunkConfiguration.java

package roy.springbatch.batChunk;import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.transaction.PlatformTransactionManager;
import roy.springbatch.batChunk.listener.BatChunkListener;
import roy.springbatch.batChunk.reader.BatChunkReader;
import roy.springbatch.batChunk.writer.BatChunkWriter;import java.util.Map;@Configuration
@EnableBatchProcessing
public class BatChunkConfiguration {@Autowiredprivate JobBuilderFactory jobBuilderFactory;@Autowiredprivate StepBuilderFactory stepBuilderFactory;@Autowiredprivate BatChunkWriter batChunkWriter;@Autowiredprivate PlatformTransactionManager dbWriteManager;@Bean@Scope("prototype")public ItemReader<Map<String, String>> readerByMyBatis() {return new BatChunkReader();}@Beanpublic Job insertJob(BatChunkListener listener){String jobName = "InsertJob:" + System.currentTimeMillis();return jobBuilderFactory.get(jobName).start(stepInsert()).listener(listener).build();}@Beanpublic Step stepInsert(){return stepBuilderFactory.get("stepInsert").<Map<String, String>, Map<String, String>>chunk(1).reader(readerByMyBatis()).writer(batChunkWriter).transactionManager(dbWriteManager).allowStartIfComplete(true).build();}
}

6. 测试:

三. 代码下载:SpringBatch Sample


http://www.ppmy.cn/news/106510.html

相关文章

LTE网络的RSRQ、RSRP、SNR

内容来源openai: LTE网络对RSRQ的要求&#xff1a; LTE网络对RSRQ的要求是在正常情况下&#xff0c;RSRQ应该保持在-10dB到-20dB之间。如果RSRQ低于-20dB&#xff0c;信号质量会变得非常差&#xff0c;可能会导致数据传输速度变慢或者连接中断。如果RSRQ高于-10dB&#xff0c…

关于两个项目用的不是同一个node的解决 办法

问题描述&#xff1a; 两个前端项目&#xff0c;使用的不是同一个版本的node 和npm &#xff0c;导致总有一个项目启动不了&#xff0c;如何解决这个问题呐&#xff1f; 解决工具&#xff1a; nvm&#xff1a;node 版本管理器&#xff0c;也就是说&#xff1a;一个 nvm 可以管理…

企业级信息系统开发——Spring Boot加载自定义配置文件

文章目录 一、使用PropertySource加载自定义配置文件&#xff08;一&#xff09;创建Spring Boot Web项目ConfigDemo01&#xff08;二&#xff09;创建自定义配置文件&#xff08;三&#xff09;创建自定义配置类&#xff08;四&#xff09;编写测试方法&#xff08;五&#xf…

Flutter的手势识别功能实现GestureDetector

GestureDetector简介 GestureDetector 是 Flutter 中一个非常常用的小部件&#xff0c;它提供了许多手势识别的功能&#xff0c;包括点击、双击、长按、拖动、缩放等等。 使用方法 GestureDetector 可以包裹其他部件&#xff0c;当用户在这些部件上进行手势操作时&#xff0…

一文搞懂激活函数(Sigmoid/ReLU/LeakyReLU/PReLU/ELU)

深度学习算法之前的机器学习算法&#xff0c;并不需要对训练数据作概率统计上的假设&#xff1b;但为了让深度学习算法有更好的性能&#xff0c;需要满足的关键要素之一&#xff0c;就是&#xff1a;网络的输入数据服从特定的分布&#xff1a; 数据分布应该是零均值化的&#…

巧计口诀-软件测试的生命周期,黑盒测试设计方法

又到了找工作的日子&#xff0c;背诵这些基本知识和概念又开始了。我找到一个好办法背诵这些方法&#xff1a; 软件测试的生命周期是“分级设编执评” &#xff0c;这样理解啊&#xff1a;“有个公司啊&#xff0c;要施行分级设计编制&#xff0c;就要执行评估了&#xff0c;大…

好用的自动化框架-Allure

概述 报告主要包含总览、类别、测试套件、图表、时间刻度、功能、包等7大部分&#xff0c;支持自定义诸多信息&#xff0c;包括附件添加、缺陷链接、案例链接、测试步骤、Epic、Feature、Story、Title、案例级别等&#xff0c;相当强大。 allure与pytest的结合使用可以呈现完…

golang 协程的实现原理

核心概念 要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是G, M和P, 没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在. G (goroutine) G是goroutine的头文字, goroutine可以解释为受管理的…