先搞懂几个概念
Job Respository: 作业仓库,负责Job、Step执行过程中的状态保存
Job launcher: 作业调度器,提供执行Job的入口
Job:作业,由多个step组成,封装整个批处理操作
Step:作业步,Job的一个执行环节,由多个或者一个step组装成Job
Tasklet:step中具体执行逻辑的操作,可以重复执行,可以设置具体的同步、异步操作等
Chunk: 给定数量Item的集合,可以定义对Chunk的读操作、处理操作、写操作、提交间隔等
Item:一条数据记录
ItemReader:从数据源中读取Item
ItemProcessor:在Item写入数据源之前,对数据进行处理
ItemWriter:将Item批量写入数据源
实战部分
使用maven创建的工程
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>core-batch</groupId> <artifactId>core-batch</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>core-batch</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-infrastructure</artifactId> <version>3.0.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-core</artifactId> <version>3.0.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-test</artifactId> <version>3.0.1.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
定义对象领域
package com.batman.core.batch; //定义领域对象 public class CreditBill { private String accountID = ""; private String name = ""; private double amount = 0; private String date; private String address; public String getAccountID() { return accountID; } public void setAccountID(String accountID) { this.accountID = accountID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
定义数据处理类
package com.batman.core.batch; import org.springframework.batch.item.ItemProcessor; public class CreditBillProcessor implements ItemProcessor<CreditBill, CreditBill>{ public CreditBill process(CreditBill bill) throws Exception { System.out.println(bill.toString()); return bill; } }
创建配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-autowire="byName"> <!-- 配置任务仓库 --> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> </bean> <!-- 配置任务调度器 用来启动Job--> <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> <property name="jobRepository" ref="jobRepository"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/> </beans>
创建job
<?xml version="1.0" encoding="UTF-8"?> <bean:beans xmlns="http://www.springframework.org/schema/batch" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd"> <bean:import resource="classpath:job-context.xml"/> <!-- 定义一个批处理作业 --> <job id="billJob"> <!-- 定义个billStep的作业步,有一个面向批的操作组成 --> <step id="billStep"> <!-- 定义批处理操作采用定义的事务管理器,负责批处理中事务管理操作 --> <tasklet transaction-manager="transactionManager"> <!-- 定义了面向批的操作,定义了读操作csvItemReader,处理操作 creditBillProcessor,写操作csvItemWriter commit-interval表示提交间隔的大小,即每处理两条数据进行一次写操作--> <chunk reader="csvItemReader" writer="csvItemWriter" processor="creditBillProcessor" commit-interval="2"> </chunk> </tasklet> </step> </job> <!-- 读取信用卡账单文件,CSV格式 --> <bean:bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> <!-- 读取文件资源 --> <bean:property name="resource" value="classpath:credit-card-bill-201303.csv"/> <!-- 通过lineMapper可以把文本中的一行转换成领域对象CreditBill --> <bean:property name="lineMapper"> <bean:bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> <!-- 定义文本中的分割符号 --> <bean:property name="lineTokenizer" ref="lineTokenizer"/> <!-- 根据lineTokenizer中定义的names属性映射到creditBill中,最终组装成信用卡账单对象 --> <bean:property name="fieldSetMapper"> <bean:bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"> <bean:property name="prototypeBeanName" value="creditBill"> </bean:property> </bean:bean> </bean:property> </bean:bean> </bean:property> </bean:bean> <!-- lineTokenizer --> <bean:bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> <bean:property name="delimiter" value=","/> <bean:property name="names"> <bean:list> <bean:value>accountID</bean:value> <bean:value>name</bean:value> <bean:value>amount</bean:value> <bean:value>date</bean:value> <bean:value>address</bean:value> </bean:list> </bean:property> </bean:bean> <!-- 写信用卡账单文件,CSV格式 --> <bean:bean id="csvItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step"> <bean:property name="resource" value="file:target/outputFile.csv"/> <bean:property name="lineAggregator"> <bean:bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator"> <bean:property name="delimiter" value=","></bean:property> <bean:property name="fieldExtractor"> <bean:bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor"> <bean:property name="names" value="accountID,name,amount,date,address"> </bean:property> </bean:bean> </bean:property> </bean:bean> </bean:property> </bean:bean> <bean:bean id="creditBill" scope="prototype" class="com.batman.core.batch.CreditBill"> </bean:bean> <!-- 负责处理读入的数据 --> <bean:bean id="creditBillProcessor" scope="step" class="com.batman.core.batch.CreditBillProcessor"> </bean:bean> </bean:beans>
创建main
package com.batman.core.batch; 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 JobLaunch { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "job.xml"); //获取作业调度器 JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher"); //获取任务对象 Job job = (Job) context.getBean("billJob"); try { //通过JobLauncher的run方法执行billJob任务 JobExecution result = launcher.run(job, new JobParameters()); System.out.println(result.toString()); } catch (Exception e) { e.printStackTrace(); } } }