您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring Batch的概念和作用是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring Batch的概念和作用是什么”吧!
一、Spring Batch的概念知識
1.1、分層架構(gòu)
1.2、關(guān)鍵概念
1.2.1、JobRepository
1.2.2、任務(wù)啟動器JobLauncher
1.2.3、任務(wù)Job
1.2.4、步驟Step
1.2.5、輸入——處理——輸出
二、代碼實(shí)例
2.1、基本框架
2.2、輸入——處理——輸出
2.2.1、讀取ItemReader
2.2.2、處理ItemProcessor
2.2.3、輸出ItremWriter
2.3、Step
2.4、Job
2.5、運(yùn)行
三、監(jiān)聽Listener
Spring Batch
的分層架構(gòu)圖如下:
可以看到它分為三層,分別是:
Application
應(yīng)用層:包含了所有任務(wù)batch jobs
和開發(fā)人員自定義的代碼,主要是根據(jù)項(xiàng)目需要開發(fā)的業(yè)務(wù)流程等。
Batch Core
核心層:包含啟動和管理任務(wù)的運(yùn)行環(huán)境類,如JobLauncher
等。
Batch Infrastructure
基礎(chǔ)層:上面兩層是建立在基礎(chǔ)層之上的,包含基礎(chǔ)的讀入reader
和寫出writer
、重試框架等。
理解下圖所涉及的概念至關(guān)重要,不然很難進(jìn)行后續(xù)開發(fā)和問題分析。
專門負(fù)責(zé)與數(shù)據(jù)庫打交道,對整個(gè)批處理的新增、更新、執(zhí)行進(jìn)行記錄。所以Spring Batch
是需要依賴數(shù)據(jù)庫來管理的。
負(fù)責(zé)啟動任務(wù)Job
。
Job
是封裝整個(gè)批處理過程的單位,跑一個(gè)批處理任務(wù),就是跑一個(gè)Job
所定義的內(nèi)容。
上圖介紹了Job
的一些相關(guān)概念:
Job
:封裝處理實(shí)體,定義過程邏輯。
JobInstance
:Job
的運(yùn)行實(shí)例,不同的實(shí)例,參數(shù)不同,所以定義好一個(gè)Job
后可以通過不同參數(shù)運(yùn)行多次。
JobParameters
:與JobInstance
相關(guān)聯(lián)的參數(shù)。
JobExecution
:代表Job
的一次實(shí)際執(zhí)行,可能成功、可能失敗。
所以,開發(fā)人員要做的事情,就是定義Job
。
Step
是對Job
某個(gè)過程的封裝,一個(gè)Job
可以包含一個(gè)或多個(gè)Step
,一步步的Step
按特定邏輯執(zhí)行,才代表Job
執(zhí)行完成。
通過定義Step
來組裝Job
可以更靈活地實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯。
所以,定義一個(gè)Job
關(guān)鍵是定義好一個(gè)或多個(gè)Step
,然后把它們組裝好即可。而定義Step
有多種方法,但有一種常用的模型就是輸入——處理——輸出
,即Item Reader
、Item Processor
和Item Writer
。比如通過Item Reader
從文件輸入數(shù)據(jù),然后通過Item Processor
進(jìn)行業(yè)務(wù)處理和數(shù)據(jù)轉(zhuǎn)換,最后通過Item Writer
寫到數(shù)據(jù)庫中去。
Spring Batch
為我們提供了許多開箱即用的Reader
和Writer
,非常方便。
理解了基本概念后,就直接通過代碼來感受一下吧。整個(gè)項(xiàng)目的功能是從多個(gè)csv
文件中讀數(shù)據(jù),處理后輸出到一個(gè)csv
文件。
添加依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> <dependency> <groupId>com.h3database</groupId> <artifactId>h3</artifactId> <scope>runtime</scope> </dependency>
需要添加Spring Batch
的依賴,同時(shí)使用H2
作為內(nèi)存數(shù)據(jù)庫比較方便,實(shí)際生產(chǎn)肯定是要使用外部的數(shù)據(jù)庫,如Oracle
、PostgreSQL
。
入口主類:
@SpringBootApplication @EnableBatchProcessing public class PkslowBatchJobMain { public static void main(String[] args) { SpringApplication.run(PkslowBatchJobMain.class, args); } }
也很簡單,只是在Springboot
的基礎(chǔ)上添加注解@EnableBatchProcessing
。
領(lǐng)域?qū)嶓w類Employee
:
package com.pkslow.batch.entity; public class Employee { String id; String firstName; String lastName; }
對應(yīng)的csv
文件內(nèi)容如下:
id,firstName,lastName
1,Lokesh,Gupta
2,Amit,Mishra
3,Pankaj,Kumar
4,David,Miller
因?yàn)橛卸鄠€(gè)輸入文件,所以定義如下:
@Value("input/inputData*.csv") private Resource[] inputResources; @Bean public MultiResourceItemReader<Employee> multiResourceItemReader() { MultiResourceItemReader<Employee> resourceItemReader = new MultiResourceItemReader<Employee>(); resourceItemReader.setResources(inputResources); resourceItemReader.setDelegate(reader()); return resourceItemReader; } @Bean public FlatFileItemReader<Employee> reader() { FlatFileItemReader<Employee> reader = new FlatFileItemReader<Employee>(); //跳過csv文件第一行,為表頭 reader.setLinesToSkip(1); reader.setLineMapper(new DefaultLineMapper() { { setLineTokenizer(new DelimitedLineTokenizer() { { //字段名 setNames(new String[] { "id", "firstName", "lastName" }); } }); setFieldSetMapper(new BeanWrapperFieldSetMapper<Employee>() { { //轉(zhuǎn)換化后的目標(biāo)類 setTargetType(Employee.class); } }); } }); return reader; }
這里使用了FlatFileItemReader
,方便我們從文件讀取數(shù)據(jù)。
為了簡單演示,處理很簡單,就是把最后一列轉(zhuǎn)為大寫:
public ItemProcessor<Employee, Employee> itemProcessor() { return employee -> { employee.setLastName(employee.getLastName().toUpperCase()); return employee; }; }
比較簡單,代碼及注釋如下:
private Resource outputResource = new FileSystemResource("output/outputData.csv"); @Bean public FlatFileItemWriter<Employee> writer() { FlatFileItemWriter<Employee> writer = new FlatFileItemWriter<>(); writer.setResource(outputResource); //是否為追加模式 writer.setAppendAllowed(true); writer.setLineAggregator(new DelimitedLineAggregator<Employee>() { { //設(shè)置分割符 setDelimiter(","); setFieldExtractor(new BeanWrapperFieldExtractor<Employee>() { { //設(shè)置字段 setNames(new String[] { "id", "firstName", "lastName" }); } }); } }); return writer; }
有了Reader-Processor-Writer
后,就可以定義Step
了:
@Bean public Step csvStep() { return stepBuilderFactory.get("csvStep").<Employee, Employee>chunk(5) .reader(multiResourceItemReader()) .processor(itemProcessor()) .writer(writer()) .build(); }
這里有一個(gè)chunk
的設(shè)置,值為5
,意思是5條記錄后再提交輸出,可以根據(jù)自己需求定義。
完成了Step
的編碼,定義Job
就容易了:
@Bean public Job pkslowCsvJob() { return jobBuilderFactory .get("pkslowCsvJob") .incrementer(new RunIdIncrementer()) .start(csvStep()) .build(); }
完成以上編碼后,執(zhí)行程序,結(jié)果如下:
成功讀取數(shù)據(jù),并將最后字段轉(zhuǎn)為大寫,并輸出到outputData.csv
文件。
可以通過Listener
接口對特定事件進(jìn)行監(jiān)聽,以實(shí)現(xiàn)更多業(yè)務(wù)功能。比如如果處理失敗,就記錄一條失敗日志;處理完成,就通知下游拿數(shù)據(jù)等。
我們分別對Read
、Process
和Write
事件進(jìn)行監(jiān)聽,對應(yīng)分別要實(shí)現(xiàn)ItemReadListener
接口、ItemProcessListener
接口和ItemWriteListener
接口。因?yàn)榇a比較簡單,就是打印一下日志,這里只貼出ItemWriteListener
的實(shí)現(xiàn)代碼:
public class PkslowWriteListener implements ItemWriteListener<Employee> { private static final Log logger = LogFactory.getLog(PkslowWriteListener.class); @Override public void beforeWrite(List<? extends Employee> list) { logger.info("beforeWrite: " + list); } @Override public void afterWrite(List<? extends Employee> list) { logger.info("afterWrite: " + list); } @Override public void onWriteError(Exception e, List<? extends Employee> list) { logger.info("onWriteError: " + list); } }
把實(shí)現(xiàn)的監(jiān)聽器listener
整合到Step
中去:
@Bean public Step csvStep() { return stepBuilderFactory.get("csvStep").<Employee, Employee>chunk(5) .reader(multiResourceItemReader()) .listener(new PkslowReadListener()) .processor(itemProcessor()) .listener(new PkslowProcessListener()) .writer(writer()) .listener(new PkslowWriteListener()) .build(); }
執(zhí)行后看一下日志:
這里就能明顯看到之前設(shè)置的chunk
的作用了。Writer
每次是處理5條記錄,如果一條輸出一次,會對IO
造成壓力。
感謝各位的閱讀,以上就是“Spring Batch的概念和作用是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Spring Batch的概念和作用是什么這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。