SpringBatch從入門到放棄002- 核心概念1

2021-01-11 鵬哥歪說

Spring -batch

SpringBatch從入門到放棄002- 核心概念1

上一篇我們通過一個例子簡單介紹了一下 Spring Batch,讓大家有個簡答的概念,今天我們來看 Spring batch 裡面具體的概念。

穿梭機:

基於Spring Boot 2.x 的 Spring Batch 入門到放棄之旅

SpringBatch從入門到放棄001- HelloWorld

本篇文章的目錄如下:

1. JobRepository配置一個 JobRepository2. JobLauncher配置一個 JobLauncher3. JobExplorer4 JobOperator5. JobRegistry6. Batch Namespace1. JobRepository

存儲 Job 的倉庫,可以配置成 內存存儲或者資料庫存儲。如果實用資料庫可以支持重啟。

JobRepostitory 的接口定義如下:

JobRepository接口定義

JobRepositoryFactoryBean的接口籤名如下,裡面我們可以看出需要指定數據源等信息。

JobRepositoryFactoryBean的接口籤名

配置一個 JobRepository

我們知道,在@EnableBatchProcess 註解之後,Spring Boot 會幫我自動配置一套 Spring Batch 的配置, 我們來通過 Spring Boot 的源碼來解析一下如何注入一個 JobRepository。

Spring Boot的所有自動配置都包含在spring.boot.autoconfigure.jar 這個 jar 中。根據 Spring 的加載規則,自動配置的類需要 spring.factories 中引入,所以我們打開這個文件,找到 batch 相關的配置

Spring Boot2 中自動配置類

org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration 但是我們在這個類中只看到 JobRepository 的引用,並沒有他的 Bean註解,所以一定是在這個之前已經引入了這個類的配置:

@Configuration@ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class })@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)@ConditionalOnBean(JobLauncher.class)@EnableConfigurationProperties(BatchProperties.class)@Import(BatchConfigurerConfiguration.class)public class BatchAutoConfiguration {如果我們的猜想沒錯的話,從上邊我們不難看出JobRepository 的定義一定是在 BatchConfigurerConfiguration.class 中,我們打開這個類。

@ConditionalOnClass(PlatformTransactionManager.class)@ConditionalOnMissingBean(BatchConfigurer.class)@Configurationclass BatchConfigurerConfiguration { @Configuration @ConditionalOnMissingBean(name = "entityManagerFactory") static class JdbcBatchConfiguration { @Bean public BasicBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) { return new BasicBatchConfigurer(properties, dataSource, transactionManagerCustomizers.getIfAvailable()); } } @Configuration @ConditionalOnClass(EntityManagerFactory.class) @ConditionalOnBean(name = "entityManagerFactory") static class JpaBatchConfiguration { @Bean public JpaBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers, EntityManagerFactory entityManagerFactory) { return new JpaBatchConfigurer(properties, dataSource, transactionManagerCustomizers.getIfAvailable(), entityManagerFactory); } }}然並卵,我們還是沒有找到對應的 JobRepository的註解,等等,BasicBatchConfigurer.java這個好像是貓膩,我們打開這個這個類,果真裡面就有private JobRepository jobRepository; 我們開看一下他是怎麼初始化的,首先裡面有個@PostConstruct 註解的initialize()方法,

@PostConstruct public void initialize() { try { this.transactionManager = buildTransactionManager(); this.jobRepository = createJobRepository(); this.jobLauncher = createJobLauncher(); this.jobExplorer = createJobExplorer(); } catch (Exception ex) { throw new IllegalStateException("Unable to initialize Spring Batch", ex); } }在這個方法裡面調用了createJobRepository(),下邊就是默認創建JobRepository所需要傳入的屬性。如果我們自定義JobRepository,同樣的我們也需要傳入這些屬性。

protected JobRepository createJobRepository() throws Exception { JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); PropertyMapper map = PropertyMapper.get(); map.from(this.dataSource).to(factory::setDataSource); map.from(this::determineIsolationLevel).whenNonNull().to(factory::setIsolationLevelForCreate); map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); map.from(this::getTransactionManager).to(factory::setTransactionManager); factory.afterPropertiesSet(); return factory.getObject(); }你也許會有疑問,BatchConfigurerConfiguration.java 中有這個註解 @ConditionalOnMissingBean(BatchConfigurer.class),而我們打開BatchConfigurer.java 這個接口的實現類,發現有個DefaultBatchConfigurer.java 被註解了進來,那為什麼BatchConfigurerConfiguration.java裡面的另外兩個註解還是生效了呢?這就是SpringBoot 設計的精妙之處了。

@Componentpublic class DefaultBatchConfigurer implements BatchConfigurer {當我們程序中注入了 Database 相關的參數,spring boot 會默認初始化一個entityManagerFactory 而一旦有兩個這個

被 static 修飾的JdbcBatchConfiguration 和 JpaBatchConfiguration就會生效,這個時候就會注入基於資料庫存儲的 JopRepository。

@ConditionalOnClass(EntityManagerFactory.class)@ConditionalOnBean(name = "entityManagerFactory")那如果不配置 Datasource 呢?如果我們程序中不注入一個 Datasource ,程序就會報錯。也就是說 Spring Boot 默認是必須使用資料庫版本的。如果想不使用,只能自己實現一個 BatchConfig.java 接口了。

2. JobLauncher

一個根據 Job 名稱和 JobParameters 觸發 batch 的接口,不管觸發成功與否都會返回一個 JobExecution 對象。如果當前的 JobName 和 JobParameters 已經對應一個 JobExecution ,則返回這個,如果麼有則新建一個。

定義如下:

public interface JobLauncher { public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException;}配置一個 JobLauncher

正常情況下Spring boot 會幫我們創建一個默認的 JobLauncher,如果想客戶化這個配置,可以參考 JobRepository.

protected JobLauncher createJobLauncher() throws Exception { SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); jobLauncher.setJobRepository(getJobRepository()); jobLauncher.afterPropertiesSet(); return jobLauncher; }3. JobExplorer

提供了在運行期Mete-Data 數據的只讀操作

JobExplorer

接口定義如下:

接口定義

參照之前的方法,下邊我們在 Spring Boot 找到的默認實現的方法:

protected JobExplorer createJobExplorer() throws Exception { PropertyMapper map = PropertyMapper.get(); JobExplorerFactoryBean factory = new JobExplorerFactoryBean(); factory.setDataSource(this.dataSource); map.from(this.properties::getTablePrefix).whenHasText().to(factory::setTablePrefix); factory.afterPropertiesSet(); return factory.getObject(); }4 JobOperator

之前介紹JobRepository 提供了對 meta-data 的增刪改查。JobExplorer則提供了在運行期對這些數據的只讀操作。但是一些常見的監視操作如,停止,重啟,匯總等對於業務操作人員是非常有用的,JobOperator 則提供了這些操作。

JobOperator 接口的定義:

JobOperator

配置一個簡單的例子:

@Bean public SimpleJobOperator jobOperator(JobExplorer jobExplorer, JobRepository jobRepository, JobRegistry jobRegistry) { SimpleJobOperator jobOperator = new SimpleJobOperator(); jobOperator.setJobExplorer(jobExplorer); jobOperator.setJobRepository(jobRepository); jobOperator.setJobRegistry(jobRegistry); jobOperator.setJobLauncher(jobLauncher); return jobOperator; }5. JobRegistry

JobRegistry (父接口為 JobLocator )並非強制使用,它能夠協助用戶在上下文中追蹤job是否可用,也能夠在應用上下文收集在其他地方(子上下文)創建的job信息。自定義的JobRegistry實現常被用於操作job的名稱或是其他屬性。框架提供了一個基於map的默認實現,能夠從job的名稱映射到job的實例

MapJobRegistry

6. Batch Namespace

Spring Boot 之後大家已經習慣了基於 JavaConfig 的配置,但是 Batch 依然支持基於 XML 的配置,在官方文檔中,基本上兩種方式的配置都會提供。上邊提到的領域模型概念在基於 XML 的配置中,雖然使用標準的 Beans 空間也可以配置,但是 Batch 還是提供了自己的命名空間,讓配置變得更方便,下邊就是一個配置的例子:

<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch https://www.springframework.org/schema/batch/spring-batch.xsd"> <job id="ioSampleJob"> <step id="step1"> <tasklet> <chunk reader="itemReader" writer="itemWriter" commit-interval="2"/> </tasklet> </step> </job> </beans:beans>上邊提到的 schema 在 spring-batch-core中有指定,我們看到現在默認的是使用 spring-batch-3.0.xsd

spring-batch.xsd

3.0的 XSD 的具體結構和約束可以在下邊路徑中找到。

spring-batch-3.0.xsd

至此 Spring Batch 的核心概念就介紹完了,下一篇我們將介紹具體的實例概念如 Job,Step 等。

相關焦點

  • SpringBatch從入門到放棄001- HelloWorld
    SpringBatch從入門到放棄001- HelloWorld經常有人問我,有沒有一個 Spring Batch 的例子可以參考一下,之前的我的回答一般是百度自己找,太多了。但是後來我發現因為 Spring Batch的版本太穩定,網上的例子大部分都是基於2.X,3.X版本的,還有就是對應的 Spring Boot 的版本也是比較老的。
  • Spring Batch 入門教程
    </artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-batch-hello-world</name> <description
  • 通過例子講解Spring Batch入門,優秀的批處理框架
    2 Spring Batch的概念知識2.1 分層架構Spring Batch的分層架構圖如下:可以看到它分為三層,分別是:Application應用層:包含了所有任務batch jobs和開發人員自定義的代碼,主要是根據項目需要開發的業務流程等。
  • Spring Batch真是個優秀的批處理框架,用完愛不釋手!
    2 Spring Batch的概念知識2.1 分層架構Spring Batch的分層架構圖如下:通過例子講解Spring Batch入門,優秀的批處理框架可以看到它分為三層,分別是:Application應用層:包含了所有任務batch jobs和開發人員自定義的代碼,主要是根據項目需要開發的業務流程等
  • Spring Batch 批處理框架技巧
    引入依賴首先我們需要引入對Spring Batch的依賴,在pom.xml文件加入下面的代碼:<dependency>    <groupId>org.springframework.batch</groupId>    <artifactId>spring-batch-core
  • 一文輕鬆搞定批處理框架 Spring Batch
    Spring Batch 不僅提供了統一的讀寫接口、豐富的任務處理方式、靈活的事務管理及並發處理,同時還支持日誌、監控、任務重啟與跳過等特性,大大簡化了批處理應用開發,將開發人員從複雜的任務配置管理過程中解放出來,使他們可以更多地去關注核心的業務處理過程。  另外我們還需要知道,Spring Batch 是一款批處理應用框架,不是調度框架。
  • SpringBatch從入門到放棄011- 一個典型的資料庫分片處理的例子
    Step 1: 創建一個Spring Batch 的工程當然首先還是需要先創建一個Spring Batch 的工程,這裡鵬哥就不浪費了筆墨了,看這篇文章就好了。參考[SpringBatch從入門到放棄001- HelloWorld]。Step 2: 定義我們的分片規則回憶我們的需求,資料庫有100條記錄,需要分5片執行,怎麼個分法?
  • Spring Batch 4.1.0.RC1,用於編寫批處理應用的框架
    Spring Batch 4.1.0.RC1 已發布,可從 Maven Central, Github 和 Pivotal 下載倉庫獲取。
  • Spring Batch 4.3.0-M2 發布,批處理應用編寫框架
    更新亮點1. 增強對 Kafka 的支持默認情況下,KafkaItemReader 從頭開始讀取主題。最初在 v4.2 中引入此讀取器時,無法將其配置為從自定義偏移量讀取記錄。在此版本中,可以將讀取器配置為從存儲在 Kafka 中的偏移量開始。2.
  • SpringSecurity + JWT,從入門到精通!
    權限系統躲不開的概念RBAC1相對於 RBAC0 模型來說,增加了子角色,引入了繼承的概念。RBAC3 模型即,RBAC1,RBAC2,兩者模型全部累計,稱為統一模型。對於下圖中的系統而言,擁有,計劃管理,客戶管理,合同管理,出入庫通知單管理,糧食安全追溯,糧食統計查詢,設備管理這幾個頁面,對這幾個頁面的訪問,以及是否能夠訪問到菜單,都屬於權限
  • spring security 整合 springboot 入門案例
    序言前面我們學習了 spring security 與 springmvc 的整合入門教程。這一節我們來學習一下 spring security 與 springboot 整合,為了力求簡單,此處不演示資料庫相關操作。
  • SpringBatch組合寫,複雜業務邏輯批處理必備
    複合寫功能實現MyBatis官方提供了組合寫人ItemWriter:org.springframework.batch.item.support.CompositeItemWriter,但是很遺憾,使用起來並不方便,主要體現在參數的傳遞上。場景複合寫要解決的應用場景是一個Step更新一張主張,多張從表、子表。
  • Spring SPI和Spring Boot SPI - 第345篇
    一、Spring SPI1.1執行流程Spring中使用的類是SpringFactoriesLoader,在org.springframework.core.io.support包中,大體的執行流程:(1)SpringFactoriesLoader
  • 從基礎概念到實現,小白如何快速入門PyTorch
    ])6.0>>> x[0][1] = 8>>> print(x)1  8  34  5  6[torch.FloatTensor of size 2x3]若 x 為我們定義的 5×3 Torch 張量,且初始化數值服從-1 到 1 的均勻分布,
  • 原創書籍 |《VBA從入門到放棄》
    📚how-to-give-up-learning-VBA📖VBA從入門到放棄作者:王文鋮演示系統和Office版本:Windows 10;Office 2016。隨著公司規模的迅速擴大,18年的專賣店數量差不多是上述的3倍,同樣,所耗時間按理也至少是3倍,也就是1周的時間也無法完成工作,大概2周。在所耗時間與所得收穫之間的天平愈加向前者傾斜的過程中,我開始思考如何解決上面的麻煩。
  • kafka入門(原理-搭建-簡單使用)
    :kafka:bootstrap-servers: 192.168.200.130:9092 #此處是我虛擬機上linux的ip kafak的默認埠為9092producer: #生產者acks: 1client-id: kafka-producerbatch-size: 5buffer-memory
  • 面試官:你了解spring嗎?spring的兩大核心是什麼?
    IOC的入門案例a. 創建一個java項目spring並不是非要在javaweb環境下才可以使用,一個普通的java程序中也可以使用Spring。b. 導入Spring的libs目錄下IOC相關的jar包c.
  • 15分鐘入門 TensorFlow 1.x
    在入門深度學習時,最開始接觸的是pytorch或者tf2.x框架,可在讀一些論文的代碼時,不少是基於tf1.x實現的,特別是2019年前的論文。tf1.x,與tf2.x或者pytorch的代碼風格或者API都有很大的差異,這對我這個業餘小白在學習過程中產生了比較大的障礙。
  • Eureka中的核心概念
    前面的文章我們是以實際代碼操作為主,這篇文章我想對前面三篇文章中涉及到的一些知識點再進行詳細的梳理,對於一些前面未涉及到的配置再做進一步的說明。首先,通過前面三篇文章的學習,小夥伴們已經發現了Eureka服務治理體系中涉及到三個核心概念:服務註冊中心、服務提供者以及服務消費者,本文將從這三個方面來對Eureka服務治理體系進行一個詳細的說明。
  • 【深度學習實戰】從基礎概念到實現,小白如何快速入門PyTorch
    ])6.0>>> x[0][1] = 8>>> print(x)1  8  34  5  6[torch.FloatTensor of size 2x3]若 x 為我們定義的 5×3 Torch 張量,且初始化數值服從-1 到 1 的均勻分布,