Spring Batch - 快速指南


Spring Batch - 概述

批处理是一种处理模式,涉及执行一系列自动化的复杂作业,无需用户交互。批处理处理大量数据并运行很长时间。

一些企业应用程序需要处理大量数据来执行涉及的操作 -

  • 基于时间的事件,例如定期计算。

  • 在大型数据集上重复处理的定期应用程序。

  • 以事务方式处理和验证可用数据的应用程序。

因此,企业应用程序中使用批处理来执行此类事务。

什么是 Spring 批处理

Spring Batch 是一个轻量级框架,用于开发企业应用程序中使用的批处理应用程序。

除了批量处理之外,该框架还提供以下功能 -

  • 包括日志记录和跟踪
  • 交易管理
  • 作业处理统计
  • 作业重启
  • 跳过和资源管理

您还可以使用其分区技术来扩展 Spring Batch 应用程序。

Spring批处理的特点

以下是 Spring Batch 的显着特征 -

  • 灵活性- Spring Batch 应用程序非常灵活。您只需更改 XML 文件即可改变应用程序中的处理顺序。

  • 可维护性- Spring Batch 应用程序易于维护。Spring Batch 作业包含步骤,每个步骤都可以解耦、测试和更新,而不影响其他步骤。

  • 可扩展性- 使用分区技术,您可以扩展 Spring Batch 应用程序。这些技术使您能够 -

    • 并行执行作业的步骤。

    • 并行执行单个线程。

  • 可靠性- 如果发生任何故障,您可以通过解耦步骤从确切的停止位置重新启动作业。

  • 支持多种文件格式- Spring Batch 为大量读取器和写入器提供支持,例如 XML、平面文件、CSV、MYSQL、Hibernate、JDBC、Mongo、Neo4j 等。

  • 启动作业的多种方式- 您可以使用 Web 应用程序、Java 程序、命令行等启动 Spring Batch 作业。

除此之外,Spring Batch 应用程序还支持 -

  • 失败后自动重试。

  • 在批处理执行期间和完成批处理后跟踪状态和统计数据。

  • 运行并发作业。

  • 日志记录、资源管理、跳过和重新启动处理等服务。

春季批次 - 环境

在本章中,我们将介绍如何在 Eclipse IDE 中设置 Spring Batch 环境。在继续安装之前,请确保您的系统中已安装 Eclipse。如果没有,请在您的系统中下载并安装 Eclipse。

有关 Eclipse 的更多信息,请参阅我们的Eclipse 教程。

在 Eclipse 上设置 Spring Batch

按照下面给出的步骤在 Eclipse 上设置 Spring Batch 环境。

步骤 1 - 安装 Eclipse 并打开一个新项目,如以下屏幕截图所示。

新项目

步骤 2 - 创建一个示例 Spring Batch 项目,如下所示。

项目名

步骤 3 - 右键单击​​该项目并将其转换为 Maven 项目,如下所示。将其转换为 Maven 项目后,它将为您提供一个Pom.xml,您需要在其中提及所需的依赖项。此后,这些jar文件将自动下载到您的项目中。

配置

步骤 4 - 现在,在项目的pom.xml中,复制并粘贴以下内容(Spring Batch 应用程序的依赖项)并刷新项目。

<project xmlns = "http://maven.apache.org/POM/4.0.0" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 
   http://maven.apache.org/maven-v4_0_0.xsd"> 
   <modelVersion>4.0.0</modelVersion> 
   <groupId>com.tutorialspoint</groupId> 
   <artifactId>SpringBatchSample</artifactId> 
   <packaging>jar</packaging> 
   <version>1.0-SNAPSHOT</version> 
   <name>SpringBatchExample</name>
   <url>http://maven.apache.org</url>  

   <properties> 
      <jdk.version>1.8</jdk.version> 
      <spring.version>5.3.14</spring.version> 
      <spring.batch.version>4.3.4</spring.batch.version> 
      <mysql.driver.version>5.1.25</mysql.driver.version> 
      <junit.version>4.11</junit.version> 
   </properties>  

   <dependencies> 
      <!-- Spring Core --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-core</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  

      <!-- Spring jdbc, for database --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-jdbc</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  

      <!-- Spring XML to/back object --> 
      <dependency> 
         <groupId>org.springframework</groupId> 
         <artifactId>spring-oxm</artifactId> 
         <version>${spring.version}</version> 
      </dependency>  

      <!-- MySQL database driver --> 
      <dependency> 
         <groupId>mysql</groupId> 
         <artifactId>mysql-connector-java</artifactId>
         <version>${mysql.driver.version}</version> 
      </dependency>  

      <!-- Spring Batch dependencies --> 
      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-core</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency> 

      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-infrastructure</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency>  

      <!-- Spring Batch unit test --> 
      <dependency> 
         <groupId>org.springframework.batch</groupId> 
         <artifactId>spring-batch-test</artifactId> 
         <version>${spring.batch.version}</version> 
      </dependency>  

      <!-- Junit --> 
      <dependency> 
         <groupId>junit</groupId> 
         <artifactId>junit</artifactId> 
         <version>${junit.version}</version> 
         <scope>test</scope> 
      </dependency> 
   </dependencies> 

   <build> 
      <finalName>spring-batch</finalName> 
      <plugins> 
         <plugin> 
            <groupId>org.apache.maven.plugins</groupId> 
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.9</version> 
            <configuration> 
               <downloadSources>true</downloadSources> 
               <downloadJavadocs>false</downloadJavadocs> 
            </configuration> 
         </plugin> 
   
         <plugin> 
            <groupId>org.apache.maven.plugins</groupId> 
            <artifactId>maven-compiler-plugin</artifactId> 
            <version>2.3.2</version> 
            <configuration> 
               <source>${jdk.version}</source> 
               <target>${jdk.version}</target> 
            </configuration> 
         </plugin> 
      </plugins> 
   </build> 
</project>    

Spring Batch - 架构

以下是 Spring Batch 架构的图示。如图所示,该架构包含三个主要组件,即应用程序、批处理核心批处理基础设施

建筑学

应用程序- 该组件包含我们使用 Spring Batch 框架编写的所有作业和代码。

Batch Core - 该组件包含控制和启动批处理作业所需的所有 API 类。

Batch 基础设施- 该组件包含应用程序和 Batch 核心组件使用的读取器、写入器和服务。

Spring Batch 的组件

下图显示了 Spring Batch 的不同组件以及它们如何相互连接。

成分

工作

在 Spring Batch 应用程序中,作业是要执行的批处理过程。它从头到尾不间断地运行。该作业进一步分为步骤(或作业包含步骤)。

我们将使用 XML 文件或 Java 类在 Spring Batch 中配置作业。以下是 Spring Batch 中作业的 XML 配置。

<job id = "jobid"> 
   <step id = "step1" next = "step2"/> 
   <step id = "step2" next = "step3"/> 
   <step id = "step3"/> 
</job>

批处理作业在标签 <job></job> 中配置。它有一个名为id的属性。在这些标签中,我们定义步骤的定义和顺序。

可重新启动- 一般来说,当作业正在运行时,我们尝试再次启动它,这被视为重新启动,它将再次启动。为了避免这种情况,您需要将可重新启动值设置为false,如下所示。

<job id = "jobid" restartable = "false" >

</job>

步骤是作业的独立部分,其中包含定义和执行作业(其部分)所需的信息

如图所示,每个步骤都由 ItemReader、ItemProcessor(可选)和 ItemWriter 组成。一项作业可能包含一个或多个步骤

读者、作者和处理者

项目读取器将数据从特定源读取到 Spring Batch 应用程序中,而项目写入器将数据从 Spring Batch 应用程序写入特定目标。

Item处理器是一个类,其中包含处理读入 Spring Batch 的数据的处理代码。如果应用程序读取“n”条记录,则处理器中的代码将在每条记录上执行。

当没有给出读取器和写入器时,tasklet充当 SpringBatch 的处理器。它只处理一个任务。例如,如果我们正在编写一个包含简单步骤的作业,其中我们从 MySQL 数据库读取数据并处理它并将其写入文件(平面),那么我们的步骤使用 -

  • 从 MySQL 数据库读取的阅读器。

  • 写入平面文件的写入器

  • 一个自定义处理器,根据我们的意愿处理数据。

<job id = "helloWorldJob"> 
   <step id = "step1"> 
      <tasklet> 
         <chunk reader = "mysqlReader" writer = "fileWriter" 
            processor = "CustomitemProcessor" ></chunk> 
      </tasklet> 
   </step> 
</ job>

Spring Batch 提供了一个长长的读者作者列表。使用这些预定义的类,我们可以为它们定义 bean。我们将在接下来的章节中更详细地讨论读者作者。

作业库

Spring Batch 中的作业存储库为 JobLauncher、Job 和 Step 实现提供创建、检索、更新和删除 (CRUD) 操作。我们将在 XML 文件中定义作业存储库,如下所示。

<job-repository id = "jobRepository"/> 

除了id之外,还有一些其他选项(可选)可用。以下是作业存储库的配置,其中包含所有选项及其默认值。

<job-repository id = "jobRepository" 
   data-source = "dataSource" 
   transaction-manager = "transactionManager" 
   isolation-level-for-create = "SERIALIZABLE" 
   table-prefix = "BATCH_" 
   max-varchar-length = "1000"/>

内存存储库- 如果您不想将 Spring Batch 的域对象保留在数据库中,您可以配置 jobRepository 的内存版本,如下所示。

<bean id = "jobRepository" 
   class = "org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean ">
   <property name = "transactionManager" ref = "transactionManager"/>
</bean>

工作启动器

JobLauncher 是一个接口,它使用给定的参数集启动 Spring Batch 作业。SampleJoblauncher是实现JobLauncher接口的类。以下是 JobLauncher 的配置。

<bean id = "jobLauncher" 
   class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
   <property name = "jobRepository" ref = "jobRepository" /> 
</bean>

作业实例

JobInstance代表作业的逻辑运行它是在我们运行作业时创建的。每个作业实例通过作业名称和运行时传递给它的参数来区分。

如果某个JobInstance执行失败,可以再次执行同一个JobInstance。因此,每个 JobInstance 可以有多个作业执行。

作业执行和步骤执行

JobExecution 和 StepExecution 表示作业/步骤的执行。它们包含作业/步骤的运行信息,例如(作业/​​步骤的)开始时间、(作业/步骤的)结束时间。

春季批次 - 应用

本教程中的几乎所有示例都包含以下文件 -

  • 配置文件(XML 文件)
  • Tasklet/处理器(Java 类)
  • 具有 setter 和 getter 的 Java 类(Java 类 (bean))
  • 映射器类(Java类)
  • 启动器类(Java 类)

配置文件

配置文件(XML)包含以下内容 -

  • 作业和步骤定义

  • Bean 定义读者作者

  • JobLauncher、JobRepository、事务管理器和数据源等组件的定义。

在我们的示例中,为了更好地理解,我们将其分为两个文件:job.xml文件(定义作业、步骤、读取器和写入器)和context.xml文件(作业启动器、作业存储库、事务管理器和数据源)。

映射器类

Mapper 类根据阅读器实现了行映射器字段集映射器等接口。它包含从阅读器获取数据并将其设置为具有settergetter方法的 Java 类(Java Bean)的代码。

JavaBean类

具有settergetter 的Java 类(Java bean)表示具有多个值的数据。它充当辅助类。我们将以此类对象的形式将数据从一个组件(读取器、写入器、处理器)传递到其他组件。

小任务/处理器

Tasklet/处理器类包含 Spring Batch 应用程序的处理代码。处理器是一个类,它接受包含读取的数据的对象,处理它,并返回处理后的数据(在表单对象中)。

发射器类

此类 (App.java) 包含启动 Spring Batch 应用程序的代码。

应用

Spring Batch - 配置

在编写 Spring Batch 应用程序时,我们将使用 Spring Batch 命名空间中提供的 XML 标签来配置作业、步骤、JobLauncher、JobRepository、事务管理器、读取器和写入器。因此,您需要在 XML 文件中包含此命名空间,如下所示。

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:batch = "http://www.springframework.org/schema/batch" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://www.springframework.org/schema/batch 

   http://www.springframework.org/schema/batch/spring-batch-2.2.xsd 
   http://www.springframework.org/schema/bean   
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> 

在以下部分中,我们将讨论 Spring Batch 命名空间中提供的各种标签、它们的属性和示例。

工作

该标签用于定义/配置 SpringBatch 的作业。它包含一组步骤,可以使用 JobLauncher 启动。

该标签有 2 个属性,如下所示 -

序列号 属性及描述
1

ID

它是作业的 ID,必须为此属性指定值。

2

可重新启动

该属性用于指定作业是否可重新启动。该属性是可选的。

以下是 SpringBatch 作业的 XML 配置。

<job id = "jobid" restartable = "false" > 
   . . . . . . . .  
   . . . . . . . .  
   . . . . . . . . // Step definitions 
</job>

该标签用于定义/配置 SpringBatch 作业的步骤。它具有以下三个属性 -

序列号 属性及描述
1

ID

它是作业的 ID,必须为此属性指定值。

2

下一个

这是指定下一步的快捷方式。

3

家长

它用于指定配置应继承的父 bean 的名称。

以下是 SpringBatch 步骤的 XML 配置。

<job id = "jobid"> 
   <step id = "step1" next = "step2"/> 
   <step id = "step2" next = "step3"/> 
   <step id = "step3"/> 
</job>

该标签用于定义/配置小任务的块。它具有以下四个属性 -

序列号 属性及描述
1

读者

它代表项目读取器 bean 的名称。它接受org.springframework.batch.item.ItemReader类型的值。

2

作家

它代表项目读取器 bean 的名称。它接受org.springframework.batch.item.ItemWriter类型的值。

3

处理器

它代表项目读取器 bean 的名称。它接受org.springframework.batch.item.ItemProcessor类型的值。

4

提交间隔

它用于指定提交事务之前要处理的项目数。

以下是 SpringBatch 块的 XML 配置。

<batch:step id = "step1"> 
   <batch:tasklet> 
      <batch:chunk reader = "xmlItemReader" 
         writer = "mysqlItemWriter" processor = "itemProcessor" commit-interval = "10"> 
      </batch:chunk> 
   </batch:tasklet> 
</batch:step> 

作业库

JobRepository Bean 用于使用关系数据库配置 JobRepository。该 bean 与org.springframework.batch.core.repository.JobRepository类型的类关联。

序列号 属性及描述
1

数据源

它用于指定定义数据源的 bean 名称。

2

事务管理器

它用于指定定义事务管理器的 bean 的名称。

3

数据库类型

它指定作业存储库中使用的关系数据库的类型。

以下是 JobRepository 的示例配置。

<bean id = "jobRepository" 
   class = "org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> 
   <property name = "dataSource" ref = "dataSource" /> 
   <property name = "transactionManager" ref="transactionManager" /> 
   <property name = "databaseType" value = "mysql" /> 
</bean> 

工作启动器

JobLauncher bean 用于配置 JobLauncher。它与org.springframework.batch.core.launch.support.SimpleJobLauncher类(在我们的程序中)相关联。该 bean 有一个名为jobrepository的属性,它用于指定定义 jobrepository 的 bean 的名称

以下是 jobLauncher 的示例配置。

<bean id = "jobLauncher" 
   class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
   <property name = "jobRepository" ref = "jobRepository" /> 
</bean>

事务管理器

TransactionManager bean 用于使用关系数据库配置 TransactionManager。该bean与org.springframework.transaction.platform.TransactionManager类型的类关联。

<bean id = "transactionManager"
   class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

数据源

数据源 bean 用于配置数据源该 bean 与org.springframework.jdbc.datasource.DriverManagerDataSource类型的类关联。

序列号 属性及描述
1

驱动程序类名

这指定用于连接数据库的驱动程序的类名。

2

网址

这指定了数据库的 URL。

3

用户名

这指定连接数据库的用户名。

4

密码

这指定了连接数据库的密码。

以下是数据源的配置示例。

<bean id = "dataSource" 
   class = "org.springframework.jdbc.datasource.DriverManagerDataSource"> 
   <property name = "driverClassName" value = "com.mysql.jdbc.Driver" /> 
   <property name = "url" value = "jdbc:mysql://localhost:3306/details" /> 
   <property name = "username" value = "myuser" /> 
   <property name = "password" value = "password" /> 
</bean> 

Spring Batch - 读取器、写入器和处理器

Item Reader将数据从特定源读取到 Spring Batch 应用程序中,而Item Writer将数据从 Spring Batch 应用程序写入特定目标。

Item处理器是一个类,其中包含处理读入 Spring Batch 的数据的处理代码。如果应用程序读取 n 条记录,则处理器中的代码将在每条记录上执行。

块是tasklet子元素。它用于执行读、写和处理操作。我们可以使用此元素在如下所示的步骤中配置读取器、写入器和处理器。

<batch:job id = "helloWorldJob"> 
   <batch:step id = "step1"> 
      <batch:tasklet> 
         <batch:chunk reader = "cvsFileItemReader" writer = "xmlItemWriter" 
            processor = "itemProcessor" commit-interval = "10"> 
         </batch:chunk> 
      </batch:tasklet> 
   </batch:step> 
</batch:job>

Spring Batch 提供读取器和写入器从各种文件系统/数据库(例如 MongoDB、Neo4j、MySQL、XML、平面文件、CSV 等)读取和写入数据。

要在应用程序中包含读取器,您需要为该读取器定义一个 bean,为该 bean 内的所有必需属性提供值,并将此类 bean 的id作为值传递给块元素读取器的属性(与作家)。

项目阅读器

它是读取数据的(批处理过程)步骤的实体。ItemReader 一次读取一个项目。Spring Batch 提供了一个ItemReader接口。所有读者都实现这个接口。

以下是 Spring Batch 提供的一些预定义的 ItemReader 类,用于从各种来源读取数据。

读者 目的
FlatFILEItemReader 从平面文件中读取数据。
StaxEventItemReader 从 XML 文件中读取数据。
存储过程项读取器 从数据库的存储过程中读取数据。
JDBCPagingItemReader 从关系数据库数据库中读取数据。
MongoItemReader 从 MongoDB 读取数据。
Neo4jItemReader 从 Neo4jItemReader 读取数据。

我们需要通过创建 bean 来配置ItemReaders 。以下是StaxEventItemReader的示例,它从 XML 文件读取数据。

<bean id = "mysqlItemWriter" 
   class = "org.springframework.batch.item.xml.StaxEventItemWriter"> 
   <property name = "resource" value = "file:xml/outputs/userss.xml" /> 
   <property name = "marshaller" ref = "reportMarshaller" /> 
   <property name = "rootTagName" value = "Tutorial" /> 
</bean> 

<bean id = "reportMarshaller" 
   class = "org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
   <property name = "classesToBeBound"> 
      <list> 
         <value>Tutorial</value> 
      </list> 
   </property> 
</bean> 

正如所观察到的,在配置时,我们需要指定所需读取器的相应类名,并且需要为所有所需属性提供值。

项目编写者

它是写入数据的批处理步骤的元素。ItemWriter 一次写入一个项目。Spring Batch 提供了一个ItemWriter接口。所有的作者都实现了这个接口。

以下是 Spring Batch 提供的一些预定义的 ItemWriter 类,用于从各种来源读取数据。

作家 目的
FlatFILEItemWriter 将数据写入平面文件。
StaxEventItemWriter 将数据写入 XML 文件。
存储过程项编写器 将数据写入数据库的存储过程。
JDBCPagingItemWriter 将数据写入关系数据库数据库。
MongoItemWriter 将数据写入 MongoDB。
Neo4jItemWriter 将数据写入 Neo4j。

同样,我们需要通过创建 bean 来配置 ItemWriter。以下是将数据写入 MySQL 数据库的JdbcCursorItemReader示例。

<bean id = "dbItemReader"
   class = "org.springframework.batch.item.database.JdbcCursorItemReader" scope = "step">
   <property name = "dataSource" ref = "dataSource" />
   <property name = "sql" value = "select * from tutorialsdata" />
   <property name = "rowMapper">
      <bean class = "TutorialRowMapper" /> 
   </property>
</bean>

物品处理器

ItemProcessor - ItemProcessor 用于处理数据。当给定项目无效时,它返回null,否则它处理给定项目并返回处理结果。接口ItemProcessor<I,O>表示处理器。

Tasklet 类- 当没有给出读取器写入器时,Tasklet 充当 SpringBatch 的处理器。它只处理单个任务。

我们可以通过实现包org.springframework.batch.item.ItemProcessor的接口ItemProcessor来定义自定义项目处理器。此 ItemProcessor 类接受一个对象并处理数据,并将处理后的数据作为另一个对象返回。

在批处理过程中,如果读取“n”条记录或数据元素,则对于每条记录,它将读取数据,处理数据,并将数据写入写入器中。为了处理数据,它依赖于所传递的处理器。

例如,假设您已编写代码来加载特定的 PDF 文档、创建新页面、以表格格式将数据项写入 PDF。如果执行此应用程序,它会从 XML 文档中读取所有数据项,将它们存储在 MySQL 数据库中,并将它们打印在给定 PDF 文档的各个页面中。

例子

以下是一个示例 ItemProcessor 类。

import org.springframework.batch.item.ItemProcessor;  

public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {  
   
   @Override 
   public Tutorial process(Tutorial item) throws Exception {  
      System.out.println("Processing..." + item); 
      return item; 
   } 
} 

Spring Batch - 基本应用

本章向您展示基本的 Spring Batch 应用程序。它只会执行一个tasklet来显示一条消息。

我们的 Spring Batch 应用程序包含以下文件 -

  • 配置文件- 这是一个 XML 文件,我们在其中定义作业和作业步骤。(如果应用程序也涉及读取器和写入器,则读取器写入器的配置也包含在该文件中。)

  • Context.xml - 在此文件中,我们将定义作业存储库、作业启动器和事务管理器等 bean。

  • Tasklet 类- 在此类中,我们将编写处理代码作业(在本例中,它显示一条简单的消息)

  • Launcher 类- 在此类中,我们将通过运行作业启动器来启动批处理应用程序。

作业配置文件

以下是我们示例 Spring Batch 应用程序的配置文件。

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:batch = "http://www.springframework.org/schema/batch" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://www.springframework.org/schema/batch 
      http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd "> 
   <import resource="context.xml" />      
   <!-- Defining a bean --> 
   <bean id = "tasklet" class = "a_sample.MyTasklet" />  
   <!-- Defining a job--> 
   <batch:job id = "helloWorldJob">  
      <!-- Defining a Step --> 
      <batch:step id = "step1"> 
         <tasklet ref = "tasklet"/>   
      </batch:step>    
   </batch:job>  
</beans> 

上下文.xml

以下是我们的 Spring Batch 应用程序的context.xml

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">  
   
   <bean id = "jobRepository"   
      class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> 
      <property name = "transactionManager" ref = "transactionManager" /> 
   </bean>     
     
   <bean id = "transactionManager" 
      class = "org.springframework.batch.support.transaction.ResourcelessTransactionManager" />  
   <bean id = "jobLauncher" 
      class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
      <property name = "jobRepository" ref = "jobRepository" /> 
   </bean> 
</beans> 

Tasklet.java

以下是显示一条简单消息的 Tasklet 类。

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;  

public class MyTasklet implements Tasklet { 
   
   @Override 
   public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {  
      System.out.println("Hello This is a sample example of spring batch"); 
      return RepeatStatus.FINISHED; 
   } 
} 

应用程序.java

以下是启动批处理过程的代码。

import org.springframework.batch.core.Job; 
import org.springframework.batch.core.JobExecution; 
import org.springframework.batch.core.JobParameters; 
import org.springframework.batch.core.launch.JobLauncher; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App { 
   public static void main(String[] args)throws Exception { 
  
      // System.out.println("hello"); 
      String[] springConfig  =  {"a_sample/job_hello_world.xml"};  
      
      // Creating the application context object  
      ApplicationContext context = new ClassPathXmlApplicationContext(springConfig); 
      
      // Creating the job launcher 
      JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); 
  
      // Creating the job 
      Job job = (Job) context.getBean("helloWorldJob"); 
  
      // Executing the JOB 
      JobExecution execution = jobLauncher.run(job, new JobParameters()); 
      System.out.println("Exit Status : " + execution.getStatus()); 
   }    
}

执行时,上述 SpringBatch 程序将产生以下输出 -

Apr 24, 2017 4:40:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh 
INFO:Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2ef1e4fa: startup date [Mon Apr 24 16:40:54 IST 2017]; root of context hierarchy 
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions  
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions  
INFO: Loading XML bean definitions 
Apr 24, 2017 4:40:54 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher afterPropertiesSet 
INFO: No TaskExecutor has been set, defaulting to synchronous executor. 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [FlowJob: [name=helloWorldJob]] launched with the following parameters: [{}] 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.job.SimpleStepHandler handleStep INFO: Executing step: [step1] 
Hello This is a sample example of spring batch 
Apr 24, 2017 4:40:55 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] 
Exit Status : COMPLETED

Spring Batch - XML 到 MySQL

在本章中,我们将创建一个使用 XML Reader 和 MySQL Writer 的 Spring Batch 应用程序。

Reader - 我们在应用程序中使用的阅读器是StaxEventItemReader,用于从 XML 文档读取数据。

以下是我们在此应用程序中使用的输入 XML 文档。该文档包含指定详细信息的数据记录,例如教程 ID、教程作者、教程标题、提交日期、教程图标和教程描述。

<?xml version="1.0" encoding="UTF-8"?> 
<tutorials> 
   <tutorial>      
      <tutorial_id>1001</tutorial_id> 
      <tutorial_author>Sanjay</tutorial_author> 
      <tutorial_title>Learn Java</tutorial_title> 
      <submission_date>06-05-2007</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/java/images/java-minilogo.jpg</tutorial_icon> 
      <tutorial_description>Java is a high-level programming language originally 
         developed by Sun Microsystems and released in 1995. 
         Java runs on a variety of platforms. 
         This tutorial gives a complete understanding of Java.');</tutorial_description> 
   </tutorial> 
    
   <tutorial>      
      <tutorial_id>1002</tutorial_id> 
      <tutorial_author>Abdul S</tutorial_author> 
      <tutorial_title>Learn MySQL</tutorial_title> 
      <submission_date>19-04-2007</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/mysql/images/mysql-minilogo.jpg</tutorial_icon> 
      <tutorial_description>MySQL is the most popular 
         Open Source Relational SQL database management system. 
         MySQL is one of the best RDBMS being used for developing web-based software applications. 
         This tutorial will give you quick start with MySQL 
         and make you comfortable with MySQL programming.</tutorial_description> 
   </tutorial> 
    
   <tutorial>
      <tutorial_id>1003</tutorial_id> 
      <tutorial_author>Krishna Kasyap</tutorial_author> 
      <tutorial_title>Learn JavaFX</tutorial_title> 
      <submission_date>06-07-2017</submission_date> 
      <tutorial_icon>https://www.tutorialspoint.com/javafx/images/javafx-minilogo.jpg</tutorial_icon> 
      <tutorial_description>JavaFX is a Java library used to build Rich Internet Applications. 
         The applications developed using JavaFX can run on various devices 
         such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. 
         This tutorial, discusses all the necessary elements of JavaFX that are required
         to develop effective Rich Internet Applications</tutorial_description> 
   </tutorial> 
</tutorials>

Writer -我们在应用程序中使用的writer是JdbcBatchItemWriter将数据写入 MySQL 数据库。假设我们在 MySQL 中创建了一个名为“details”的数据库表。

CREATE TABLE details.TUTORIALS( 
   tutorial_id int(10) NOT NULL, 
   tutorial_author VARCHAR(20), 
   tutorial_title VARCHAR(50), 
   submission_date VARCHAR(20), 
   tutorial_icon VARCHAR(200), 
   tutorial_description VARCHAR(1000) 
);

处理器- 我们在应用程序中使用的处理器是一个自定义处理器,它将每条记录的数据写入 PDF 文档。

在批处理过程中,如果读取了“n”条记录或数据元素,那么对于每条记录,它将读取数据,处理它,并将数据写入Writer中。为了处理数据,它依赖于所传递的处理器。在本例中,在自定义处理器类中,我们编写了代码来加载特定的 PDF 文档、创建新页面、以表格格式将数据项写入 PDF。

最后,如果您执行此应用程序,它会从 XML 文档中读取所有数据项,将它们存储在 MySQL 数据库中,并将它们打印在给定 PDF 文档的各个页面中。

作业配置文件

以下是我们示例 Spring Batch 应用程序的配置文件。在此文件中,我们将定义作业和步骤。除此之外,我们还定义了 ItemReader、ItemProcessor 和 ItemWriter 的 bean。(在这里,我们将它们与各自的类相关联,并传递所需属性的值来配置它们。)

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:batch = "http://www.springframework.org/schema/batch" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:util = "http://www.springframework.org/schema/util" 
   xsi:schemaLocation = "http://www.springframework.org/schema/batch 
    
      http://www.springframework.org/schema/batch/spring-batch-2.2.xsd 
      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
      http://www.springframework.org/schema/util     
      http://www.springframework.org/schema/util/spring-util-3.0.xsd ">  
  
   <import resource = "../jobs/context.xml" /> 
  
   <bean id = "itemProcessor" class = "CustomItemProcessor" /> 
   <batch:job id = "helloWorldJob"> 
      <batch:step id = "step1"> 
         <batch:tasklet>           
            <batch:chunk reader = "xmlItemReader" writer = "mysqlItemWriter" processor = "itemProcessor">
            </batch:chunk> 
         </batch:tasklet> 
      </batch:step> 
   </batch:job> 
                
   <bean id = "xmlItemReader" 
      class = "org.springframework.batch.item.xml.StaxEventItemReader"> 
      <property name = "fragmentRootElementName" value = "tutorial" /> 
      <property name = "resource" value = "classpath:resources/tutorial.xml" /> 
      <property name = "unmarshaller" ref = "customUnMarshaller" /> 
   </bean> 
      
   <bean id = "customUnMarshaller" class = "org.springframework.oxm.xstream.XStreamMarshaller">
      <property name = "aliases"> 
         <util:map id = "aliases"> 
            <entry key = "tutorial" value = "Tutorial" />            
         </util:map> 
      </property> 
   </bean>  
   <bean id = "mysqlItemWriter" class = "org.springframework.batch.item.database.JdbcBatchItemWriter"> 
      <property name = "dataSource" ref = "dataSource" /> 
      <property name = "sql"> 
         <value> 
            <![CDATA[insert into details.tutorials (tutorial_id, tutorial_author, tutorial_title, 
               submission_date, tutorial_icon, tutorial_description) 
               values (:tutorial_id, :tutorial_author, :tutorial_title, :submission_date, 
               :tutorial_icon, :tutorial_description);]]>
         </value> 
      </property>   
      
      <property name = "itemSqlParameterSourceProvider"> 
         <bean class = "org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" /> 
      </property> 
   </bean> 
</beans>     

上下文.xml

以下是我们的 Spring Batch 应用程序的context.xml。在此文件中,我们将定义作业存储库、作业启动器和事务管理器等 bean。

<beans xmlns = "http://www.springframework.org/schema/beans" 
   xmlns:jdbc = "http://www.springframework.org/schema/jdbc" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
      http://www.springframework.org/schema/jdbc 
      http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd"> 
   
   <!-- stored job-meta in database -->
   <bean id = "jobRepository" 
      class = "org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"> 
      <property name = "dataSource" ref = "dataSource" /> 
      <property name = "transactionManager" ref = "transactionManager" /> 
      <property name = "databaseType" value = "mysql" /> 
   </bean>  
 
   <bean id = "transactionManager" 
   class = "org.springframework.batch.support.transaction.ResourcelessTransactionMana ger" />  
   <bean id = "jobLauncher" 
      class = "org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
      <property name = "jobRepository" ref = "jobRepository" /> 
   </bean> 
  
   <!-- connect to MySQL database --> 
   <bean id = "dataSource" 
      class = "org.springframework.jdbc.datasource.DriverManagerDataSource"> 
      <property name = "driverClassName" value = "com.mysql.jdbc.Driver" /> 
      <property name = "url" value = "jdbc:mysql://localhost:3306/details" /> 
      <property name = "username" value = "myuser" /> 
      <property name = "password" value = "password" /> 
   </bean>  
 
   <!-- create job-meta tables automatically --> 
   <jdbc:initialize-database data-source = "dataSource">   
      <jdbc:script location = "org/springframework/batch/core/schema-drop-mysql.sql"/>   
      <jdbc:script location = "org/springframework/batch/core/schema-mysql.sql"/> 
   </jdbc:initialize-database> 
</beans>   

CustomItemProcessor.java

以下是处理器类。在这个类中,我们编写应用程序中的处理代码。在这里,我们加载一个 PDF 文档,创建一个新页面,创建一个表,并为每个记录插入以下值:教程 ID、教程名称、作者、提交日期。

import java.io.File; 
import java.io.IOException;  

import org.apache.pdfbox.pdmodel.PDDocument; 
import org.apache.pdfbox.pdmodel.PDPage; 
import org.apache.pdfbox.pdmodel.PDPageContentStream; 
import org.apache.pdfbox.pdmodel.font.PDType1Font; 
import org.springframework.batch.item.ItemProcessor;  

public class CustomItemProcessor implements ItemProcessor<Tutorial, Tutorial> {  
   
   public static void drawTable(PDPage page, PDPageContentStream contentStream, 
      float y, float margin, String[][] content) throws IOException { 
      final int rows = content.length; 
      final int cols = content[0].length; 
      final float rowHeight = 50; 
      final float tableWidth = page.getMediaBox().getWidth()-(2*margin); 
      final float tableHeight = rowHeight * rows; 
      final float colWidth = tableWidth/(float)cols; 
      final float cellMargin=5f;  
      
      // draw the rows 
      float nexty = y ; 
      for (int i = 0; i <= rows; i++) {   
         contentStream.drawLine(margin,nexty,margin+tableWidth,nexty); 
         nexty-= rowHeight; 
      }  
      
      //draw the columns 
      float nextx = margin; 
      for (int i = 0; i <= cols; i++) {
         contentStream.drawLine(nextx,y,nextx,y-tableHeight); 
         nextx += colWidth; 
      }  
      
      // now add the text    
      contentStream.setFont(PDType1Font.HELVETICA_BOLD,12);  
      
      float textx = margin+cellMargin; 
      float texty = y-15; 
      for(int i = 0; i < content.length; i++){ 
         for(int j = 0 ; j < content[i].length; j++){ 
            String text = content[i][j]; 
            contentStream.beginText(); 
            contentStream.moveTextPositionByAmount(textx,texty); 
            contentStream.drawString(text); 
            contentStream.endText(); 
            textx += colWidth; 
         } 
        
         texty-=rowHeight; 
         textx = margin+cellMargin; 
      } 
   }  
   
   @Override 
   public Tutorial process(Tutorial item) throws Exception { 
      System.out.println("Processing..." + item); 
   
      // Creating PDF document object 
      PDDocument doc = PDDocument.load(new File("C:/Examples/test.pdf"));     
      
      // Creating a blank page 
      PDPage page = new PDPage(); 
      doc.addPage( page ); 
      PDPageContentStream contentStream =  new PDPageContentStream(doc, page);  
      
      String[][] content = {{"Id",""+item.getTutorial_id()},
      {"Title", item.getTutorial_title()}, 
      {"Authour", item.getTutorial_author()}, 
      {"Submission Date", item.getSubmission_date()}} ;  
      drawTable(page, contentStream, 700, 100, content);       
      
      contentStream.close(); 
      doc.save("C:/Examples/test.pdf" ); 
      System.out.println("Hello"); 
      return item; 
   }    
}      

教程FieldSetMapper.java

以下是 ReportFieldSetMapper 类,它将数据设置到 Tutorial 类。

import org.springframework.batch.item.file.mapping.FieldSetMapper; 
import org.springframework.batch.item.file.transform.FieldSet; 
import org.springframework.validation.BindException;  

public class TutorialFieldSetMapper implements FieldSetMapper<Tutorial> { 
   
   @Override 
   public Tutorial mapFieldSet(FieldSet fieldSet) throws BindException {   
      // instantiating the Tutorial class 
      Tutorial tutorial = new Tutorial(); 
   
      // Setting the fields from XML 
      tutorial.setTutorial_id(fieldSet.readInt(0));   
      tutorial.setTutorial_title(fieldSet.readString(1)); 
      tutorial.setTutorial_author(fieldSet.readString(2)); 
      tutorial.setTutorial_icon(fieldSet.readString(3)); 
      tutorial.setTutorial_description(fieldSet.readString(4));   
      return tutorial;  
   }  
} 

教程.java

以下是教程课程。它是一个带有settergetter方法的简单类。

public class Tutorial { 
   private int tutorial_id; 
   private String tutorial_author; 
   private String tutorial_title; 
   private String submission_date; 
   private String tutorial_icon; 
   private String tutorial_description;   
   
   @Override 
   public String toString() { 
      return " [id=" + tutorial_id + ", author=" + tutorial_author  
         + ", title=" + tutorial_title + ", date=" + submission_date + ", icon =" 
         +tutorial_icon +", description = "+tutorial_description+"]"; 
   }  
   
   public int getTutorial_id() { 
      return tutorial_id; 
   }  
   
   public void setTutorial_id(int tutorial_id) { 
      this.tutorial_id = tutorial_id; 
   }  
   
   public String getTutorial_author() { 
      return tutorial_author; 
   }  
   
   public void setTutorial_author(String tutorial_author) { 
      this.tutorial_author = tutorial_author; 
   }  
   
   public String getTutorial_title() { 
      return tutorial_title; 
   } 
   
   public void setTutorial_title(String tutorial_title) { 
      this.tutorial_title = tutorial_title; 
   }  
   
   public String getSubmission_date() { 
      return submission_date; 
   }  
   
   public void setSubmission_date(String submission_date) { 
      this.submission_date = submission_date; 
   }  
   
   public String getTutorial_icon() { 
      return tutorial_icon; 
   }  
   
   public void setTutorial_icon(String tutorial_icon) { 
      this.tutorial_icon = tutorial_icon; 
   }  
   
   public String getTutorial_description() { 
      return tutorial_description; 
   }  
   
   public void setTutorial_description(String tutorial_description) { 
      this.tutorial_description = tutorial_description; 
   } 
}

应用程序.java

以下是启动批处理过程的代码。在本课程中,我们将通过运行 JobLauncher 来启动批处理应用程序。

public class App { 
   public static void main(String[] args) throws Exception { 
      String[] springConfig  = {    "jobs/job_hello_world.xml" };  
      
      // Creating the application context object  
      ApplicationContext context = new ClassPathXmlApplicationContext(springConfig);  
      
      // Creating the job launcher 
      JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); 
   
      // Creating the job 
      Job job = (Job) context.getBean("helloWorldJob"); 
   
      // Executing the JOB 
      JobExecution execution = jobLauncher.run(job, new JobParameters()); 
      System.out.println("Exit Status : " + execution.getStatus()); 
   }    
} 

执行此应用程序时,它将产生以下输出。

May 05, 2017 4:39:22 PM org.springframework.context.support.ClassPathXmlApplicationContext 
prepareRefresh 
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@306a30c7: 
startup date [Fri May 05 16:39:22 IST 2017]; root of context hierarchy 
May 05, 2017 4:39:23 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 
May 05, 2017 4:39:32 PM org.springframework.batch.core.job.SimpleStepHandler handleStep 
INFO: Executing step: [step1] 
Processing... [id=1001, author=Sanjay, title=Learn Java, date=06-05-2007, 
icon =https://www.tutorialspoint.com/java/images/java-mini-logo.jpg, 
description = Java is a high-level programming language originally developed by Sun Microsystems 
and released in 1995. Java runs on a variety of platforms. 
This tutorial gives a complete understanding of Java.');] 
Hello 
Processing.. [id=1002, author=Abdul S, title=Learn MySQL, date=19-04-2007, 
icon =https://www.tutorialspoint.com/mysql/images/mysql-mini-logo.jpg, 
description = MySQL is the most popular Open Source Relational SQL database management system. 
MySQL is one of the best RDBMS being used for developing web-based software applications. 
This tutorial will give you quick start with MySQL and make you comfortable with MySQL programming.] 
Hello 
Processing... [id=1003, author=Krishna Kasyap, title=Learn JavaFX, date=06-072017, 
icon =https://www.tutorialspoint.com/javafx/images/javafx-mini-logo.jpg,
description = JavaFX is a Java library used to build Rich Internet Applications. 
The applications developed using JavaFX can run on various devices 
such as Desktop Computers, Mobile Phones, TVs, Tablets, etc. 
This tutorial, discusses all the necessary elements of JavaFX 
that are required to develop effective Rich Internet Applications] 
Hello 
May 05, 2017 4:39:36 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run 
INFO: Job: [FlowJob: [name=helloWorldJob]] completed with the following parameters: [{}] 
and the following status: [COMPLETED] 
Exit Status : COMPLETED 

如果您验证数据库中的details.tutorial表,它将显示以下输出 -

教程_id 教程_作者 教程_标题 提交日期 教程_图标 教程_描述
1001 桑杰 学习Java 2007年6月5日 https://www.tutorials point.com/java/images/java-mini-logo.jpg Java 是一种高级编程语言,最初由 Sun Microsystems 开发并于 1995 年发布。Java 运行在多种平台上。本教程让您全面了解 Java。
1002 阿卜杜勒·S 学习MySQL 2007年4月19日 https://www. tutorialspoint.com /mysql/images /mysql-minilogo.jpg MySQL 是最流行的开源关系型 SQL 数据库管理系统。MySQL 是用于开发基于 Web 的软件应用程序的最佳 RDBMS 之一。本教程将帮助您快速入门 MySQL,并让您轻松掌握 MySQL 编程。
1003 学习JavaFX 克里希纳·卡夏普 2017年6月7日 https://www. tutorialspoint.com /javafx/images/ javafx-minilogo.jpg MySQL 是最流行的开源关系型 SQL 数据库管理系统。MySQL 是用于开发基于 Web 的软件应用程序的最佳 RDBMS 之一。本教程将帮助您快速入门 MySQL,并让您轻松掌握 MySQL 编程。

这将生成一个 PDF,其中每页都有记录,如下所示。

页面缩略图

Spring Batch - CSV 到 XML

在本章中,我们将创建一个简单的 Spring Batch 应用程序,它使用 CSV 读取器和 XML 写入器。

Reader -我们在应用程序中使用的阅读器是FlatFileItemReader,用于从 CSV 文件读取数据。

以下是我们在此应用程序中使用的输入 CSV 文件。该文档包含指定详细信息的数据记录,例如教程 ID、教程作者、教程标题、提交日期、教程图标和教程描述。

1001, "Sanjay", "Learn Java", 06/05/2007 
1002, "Abdul S", "Learn MySQL", 19/04/2007 
1003, "Krishna Kasyap", "Learn JavaFX", 06/07/2017

Writer - 我们在应用程序中使用的 Writer 是StaxEventItemWriter将数据写入 XML 文件。

处理器- 我们在应用程序中使用的处理器是一个自定义处理器,它仅打印从 CSV 文件读取的记录。

作业配置文件

以下是我们示例 Spring Batch 应用程序的配置文件。在此文件中,我们将定义作业和步骤。除此之外,我们还定义了 ItemReader、ItemProcessor 和 ItemWriter 的 bean。(在这里,我们将它们与各自的类相关联,并传递所需属性的值来配置它们。)

<beans xmlns = " http://www.springframework.org/schema/beans" 
   xmlns:batch = "http://www.springframework.org/schema/batch" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://www.springframework.org/schema/batch 
      http://www.springframework.org/schema/batch/spring-batch-2.2.xsd 
      http://www.springframework.org/schema/beans 
      http://www.sp