日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
SpringBatch真是個(gè)優(yōu)秀的批處理框架,用完愛不釋手!

1 前言

站在用戶的角度思考問題,與客戶深入溝通,找到錦州網(wǎng)站設(shè)計(jì)與錦州網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋錦州地區(qū)。

Spring Batch是一個(gè)輕量級(jí)的、完善的批處理框架,作為Spring體系中的一員,它擁有靈活、方便、生產(chǎn)可用的特點(diǎn)。在應(yīng)對(duì)高效處理大量信息、定時(shí)處理大量數(shù)據(jù)等場(chǎng)景十分簡(jiǎn)便。

結(jié)合調(diào)度框架能更大地發(fā)揮Spring Batch的作用。

2 Spring Batch的概念知識(shí)

2.1 分層架構(gòu)

Spring Batch的分層架構(gòu)圖如下:

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

可以看到它分為三層,分別是:

  •  Application應(yīng)用層:包含了所有任務(wù)batch jobs和開發(fā)人員自定義的代碼,主要是根據(jù)項(xiàng)目需要開發(fā)的業(yè)務(wù)流程等。
  •  Batch Core核心層:包含啟動(dòng)和管理任務(wù)的運(yùn)行環(huán)境類,如JobLauncher等。
  •  Batch Infrastructure基礎(chǔ)層:上面兩層是建立在基礎(chǔ)層之上的,包含基礎(chǔ)的讀入reader和寫出writer、重試框架等。

2.2 關(guān)鍵概念

理解下圖所涉及的概念至關(guān)重要,不然很難進(jìn)行后續(xù)開發(fā)和問題分析。

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

2.2.1 JobRepository

專門負(fù)責(zé)與數(shù)據(jù)庫(kù)打交道,對(duì)整個(gè)批處理的新增、更新、執(zhí)行進(jìn)行記錄。所以Spring Batch是需要依賴數(shù)據(jù)庫(kù)來(lái)管理的。

2.2.2 任務(wù)啟動(dòng)器JobLauncher

負(fù)責(zé)啟動(dòng)任務(wù)Job。

2.2.3 任務(wù)Job

Job是封裝整個(gè)批處理過程的單位,跑一個(gè)批處理任務(wù),就是跑一個(gè)Job所定義的內(nèi)容。

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

上圖介紹了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。

2.2.4 步驟Step

Step是對(duì)Job某個(gè)過程的封裝,一個(gè)Job可以包含一個(gè)或多個(gè)Step,一步步的Step按特定邏輯執(zhí)行,才代表Job執(zhí)行完成。

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

通過定義Step來(lái)組裝Job可以更靈活地實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯。

2.2.5 輸入——處理——輸出

所以,定義一個(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ù)庫(kù)中去。

Spring Batch為我們提供了許多開箱即用的Reader和Writer,非常方便。

3 代碼實(shí)例

理解了基本概念后,就直接通過代碼來(lái)感受一下吧。整個(gè)項(xiàng)目的功能是從多個(gè)csv文件中讀數(shù)據(jù),處理后輸出到一個(gè)csv文件。

3.1 基本框架

添加依賴:

 
 
 
 
  1.  
  2.   org.springframework.boot 
  3.   spring-boot-starter-batch 
  4.  
  5.  
  6.   com.h2database 
  7.   h2 
  8.   runtime 

需要添加Spring Batch的依賴,同時(shí)使用H2作為內(nèi)存數(shù)據(jù)庫(kù)比較方便,實(shí)際生產(chǎn)肯定是要使用外部的數(shù)據(jù)庫(kù),如Oracle、PostgreSQL。

入口主類:

 
 
 
 
  1. @SpringBootApplication 
  2. @EnableBatchProcessing 
  3. public class PkslowBatchJobMain { 
  4.     public static void main(String[] args) { 
  5.         SpringApplication.run(PkslowBatchJobMain.class, args); 
  6.     }
  7.  }

也很簡(jiǎn)單,只是在Springboot的基礎(chǔ)上添加注解@EnableBatchProcessing。

領(lǐng)域?qū)嶓w類Employee:

 
 
 
 
  1. package com.pkslow.batch.entity; 
  2. public class Employee { 
  3.     String id; 
  4.     String firstName; 
  5.     String lastName; 
  6. }

對(duì)應(yīng)的csv文件內(nèi)容如下:

 
 
 
 
  1. id,firstName,lastName 
  2. 1,Lokesh,Gupta 
  3. 2,Amit,Mishra 
  4. 3,Pankaj,Kumar 
  5. 4,David,Miller

3.2 輸入——處理——輸出

3.2.1 讀取ItemReader

因?yàn)橛卸鄠€(gè)輸入文件,所以定義如下:

 
 
 
 
  1. @Value("input/inputData*.csv") 
  2. private Resource[] inputResources; 
  3. @Bean 
  4. public MultiResourceItemReader multiResourceItemReader() 
  5. {
  6.   MultiResourceItemReader resourceItemReader = new MultiResourceItemReader(); 
  7.   resourceItemReader.setResources(inputResources); 
  8.   resourceItemReader.setDelegate(reader());
  9.   return resourceItemReader; 
  10. @Bean
  11. public FlatFileItemReader reader() 
  12.   FlatFileItemReader reader = new FlatFileItemReader(); 
  13.   //跳過csv文件第一行,為表頭 
  14.   reader.setLinesToSkip(1); 
  15.   reader.setLineMapper(new DefaultLineMapper() { 
  16.     { 
  17.       setLineTokenizer(new DelimitedLineTokenizer() { 
  18.         { 
  19.           //字段名
  20.            setNames(new String[] { "id", "firstName", "lastName" }); 
  21.         } 
  22.       }); 
  23.       setFieldSetMapper(new BeanWrapperFieldSetMapper() { 
  24.         { 
  25.           //轉(zhuǎn)換化后的目標(biāo)類 
  26.           setTargetType(Employee.class); 
  27.         } 
  28.       }); 
  29.     } 
  30.   }); 
  31.   return reader; 
  32. }

這里使用了FlatFileItemReader,方便我們從文件讀取數(shù)據(jù)。

3.2.2 處理ItemProcessor

為了簡(jiǎn)單演示,處理很簡(jiǎn)單,就是把最后一列轉(zhuǎn)為大寫:

 
 
 
 
  1. public ItemProcessor itemProcessor() { 
  2.   return employee -> { 
  3.     employee.setLastName(employee.getLastName().toUpperCase());
  4.      return employee; 
  5.   }; 
  6. }

3.2.3 輸出ItremWriter

比較簡(jiǎn)單,代碼及注釋如下:

 
 
 
 
  1. private Resource outputResource = new FileSystemResource("output/outputData.csv"); 
  2. @Bean 
  3. public FlatFileItemWriter writer() 
  4.   FlatFileItemWriter writer = new FlatFileItemWriter<>(); 
  5.   writer.setResource(outputResource); 
  6.   //是否為追加模式
  7.    writer.setAppendAllowed(true); 
  8.   writer.setLineAggregator(new DelimitedLineAggregator() { 
  9.     { 
  10.       //設(shè)置分割符
  11.        setDelimiter(","); 
  12.       setFieldExtractor(new BeanWrapperFieldExtractor() { 
  13.         { 
  14.           //設(shè)置字段 
  15.           setNames(new String[] { "id", "firstName", "lastName" }); 
  16.         } 
  17.       }); 
  18.     } 
  19.   }); 
  20.   return writer; 
  21. }

3.3 Step

有了Reader-Processor-Writer后,就可以定義Step了:

 
 
 
 
  1. @Bean 
  2. public Step csvStep() { 
  3.   return stepBuilderFactory.get("csvStep").chunk(5) 
  4.     .reader(multiResourceItemReader()) 
  5.     .processor(itemProcessor()) 
  6.     .writer(writer()) 
  7.     .build(); 
  8. }

這里有一個(gè)chunk的設(shè)置,值為5,意思是5條記錄后再提交輸出,可以根據(jù)自己需求定義。

3.4 Job

完成了Step的編碼,定義Job就容易了:

 
 
 
 
  1. @Bean 
  2. public Job pkslowCsvJob() { 
  3.   return jobBuilderFactory 
  4.     .get("pkslowCsvJob") 
  5.     .incrementer(new RunIdIncrementer()) 
  6.     .start(csvStep()) 
  7.     .build(); 
  8. }

3.5 運(yùn)行

完成以上編碼后,執(zhí)行程序,結(jié)果如下:

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

成功讀取數(shù)據(jù),并將最后字段轉(zhuǎn)為大寫,并輸出到outputData.csv文件。

4 監(jiān)聽Listener

可以通過Listener接口對(duì)特定事件進(jìn)行監(jiān)聽,以實(shí)現(xiàn)更多業(yè)務(wù)功能。比如如果處理失敗,就記錄一條失敗日志;處理完成,就通知下游拿數(shù)據(jù)等。

我們分別對(duì)Read、Process和Write事件進(jìn)行監(jiān)聽,對(duì)應(yīng)分別要實(shí)現(xiàn)ItemReadListener接口、ItemProcessListener接口和ItemWriteListener接口。因?yàn)榇a比較簡(jiǎn)單,就是打印一下日志,這里只貼出ItemWriteListener的實(shí)現(xiàn)代碼:

 
 
 
 
  1. public class PkslowWriteListener implements ItemWriteListener { 
  2.     private static final Log logger = LogFactory.getLog(PkslowWriteListener.class); 
  3.     @Override 
  4.     public void beforeWrite(List list) { 
  5.         logger.info("beforeWrite: " + list); 
  6.     } 
  7.     @Override 
  8.     public void afterWrite(List list) { 
  9.         logger.info("afterWrite: " + list); 
  10.     } 
  11.     @Override 
  12.     public void onWriteError(Exception e, List list) { 
  13.         logger.info("onWriteError: " + list); 
  14.     } 
  15. }

把實(shí)現(xiàn)的監(jiān)聽器listener整合到Step中去:

 
 
 
 
  1. @Bean 
  2. public Step csvStep() { 
  3.   return stepBuilderFactory.get("csvStep").chunk(5) 
  4.     .reader(multiResourceItemReader()) 
  5.     .listener(new PkslowReadListener()) 
  6.     .processor(itemProcessor()) 
  7.     .listener(new PkslowProcessListener()) 
  8.     .writer(writer()) 
  9.     .listener(new PkslowWriteListener()) 
  10.     .build(); 
  11. }

執(zhí)行后看一下日志:

通過例子講解Spring Batch入門,優(yōu)秀的批處理框架

這里就能明顯看到之前設(shè)置的chunk的作用了。Writer每次是處理5條記錄,如果一條輸出一次,會(huì)對(duì)IO造成壓力。

5 總結(jié)

Spring Batch還有許多優(yōu)秀的特性,如面對(duì)大量數(shù)據(jù)時(shí)的并行處理。本文主要入門介紹為主,不一一介紹,后續(xù)會(huì)專門講解。


本文題目:SpringBatch真是個(gè)優(yōu)秀的批處理框架,用完愛不釋手!
文章來(lái)源:http://m.5511xx.com/article/dpeojig.html