`

Spring Batch学习笔记(1)

 
阅读更多
    刚把上一个项目的组的框架和技术栈理顺,突然又要转到新的项目组,而且现在已经不是刚入公司的新人了,没有那么多的时间慢慢适应,赶紧上手做事才是王道,在新的项目组的技术栈中,首当其冲的就是Spring Batch,赶紧上手练习之。

Spring Batch是什么?
      Spring Batch是一个基于Spring的企业级批处理框架,按照我师父的说法,所有基于Spring的框架都是使用了spring的IoC特性,然后加上自己的一些处理规则。因此,要理解Spring Batch的设计和使用,首先需要理解批处理的机制和特点。
      所谓企业批处理就是指在企业级应用中,不需要人工干预,定期读取数据,进行相应的业务处理之后,再进行归档的这类操作。从上面的描述中可以看出,批处理的整个流程可以明显的分为3个阶段:
         1、读数据
         2、业务处理
         3、归档结果数据
另外,从定义中可以发现批处理的一个重要特色就是无需人工干预、定期执行,因此一个批处理框架,需要关注事务的粒度,日志监控,执行方式,资源管理,读数据,处理数据,写数据的解耦等方面。
      SpringBatch为我们提供了什么呢?
       1、统一的读写接口
       2、丰富的任务处理方式、
       3、灵活的事务管理及并发处理
       4、日志、监控、任务重启与跳过等特性
注意,Spring Batch未提供关于批处理任务调度的功能,因此如何周期性的调用批处理任务需要自己想办法解决,就Java来说,Quartz是一个不错的解决方案,或者写脚本处理之。

Spring Batch First Demo
      前面讲了很多Spring Batch的特性,接下来就通过一个小例子来看看Spring Batch是如何实现 批处理的读数据-》处理数据-》归档结果这一过程的。
       首先,搭建项目框架,推荐大家使用Maven或者Gradle结构的项目,不会的,赶紧学学,对于学习新技术省很多时间。一个Spring项目需要依赖的lib(可能有多,大家可以试探性的删掉一些不必要的包)如下:
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${springframework.core.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${springframework.core.version}</version>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-test</artifactId>
            <version>${spring.batch.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

项目构建好以后,首先开始写读取数据的逻辑,Spring Batch针对读、写操作提供了很多实现方式,包括文件,数据库,对于数据库的操作还提供了很多ORM框架(Hibernate,iBatis,JPA)的支持,这儿为了简单,以读文件作为例子,假设我们需要读取一个文件中所有人的信息,大于16岁的需要发信息需要发信息通知它去公安局办理身份证。简化文件如下:
TWer1,15
TWer2,21
TWer3,13
TWer4,16
TWer5,25
TWer6,45
TWer7,16
,这儿需要的Spring Batch的读文件功能就是把文件中的每一行都能转化为一个内存对象,其对应的类就是User.java
public class User {
    String name;
    int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
另外,需要在message_job.xml中配置如下内容
<bean id="messageReader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="lineMapper" ref="lineMapper"/>
        <property name="resource" value="/message/user.txt"/>
    </bean>

    <bean id="lineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
        <property name="lineTokenizer" ref="lineTokenizer"/>
        <property name="fieldSetMapper" ref="fieldSetMapper"/>
    </bean>
    <bean id="fieldSetMapper" class="com.ning.demo.UserMapper"/>
    <bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"/>
,该配置文件中除了UserMapper外,都是SpringBatch默认提供的。UserMapper.java代码如下:
public class UserMapper implements FieldSetMapper<User> {
    @Override
    public User mapFieldSet(FieldSet fieldSet) throws BindException {
        User user = new User();
        user.setName(fieldSet.readString(0));
        user.setAge(fieldSet.readInt(1));
        return user;
    }
}

这样,文件中的每一行数据都会变成一个User类的instance。
      接下来,是处理数据的过程,判断每个user的年龄,如果大于16,就生成一条Message。
public class MessageProcessor implements ItemProcessor<User, Message> {
    @Override
    public Message process(User item) throws Exception {
        Message message = null;
        if (item.getAge() > 16) {
            message = new Message();
            message.setContent(item.getName() + ",Please come to police station!");
        }
        return message;
    }
}
该类实现了SpringBatch的ItemProcessor接口,

   最后,把处理后得到的所有Message打印到Console上,
public class MessageWriter implements ItemWriter<Message> {
    @Override
    public void write(List<? extends Message> items) throws Exception {
        System.out.println("Results:");
        for (Message item : items) {
            System.out.println(item.getContent());
        }
    }
}
该类实现了SpringBatch的ItemWriter接口。SpringBatch本身提供了多种Writer实现。

  通过上面的几个步骤,把读数据,处理数据,写数据都构造出来了,那么那么是如何串联起来的呢?答案是配置文件,
    <batch:job id="messageJob">
        <batch:step id="messageStep">
            <batch:tasklet>
                <batch:chunk reader="messageReader" processor="messageProcessor" writer="messageWriter"
                             commit-interval="10"
                             chunk-completion-policy="">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
    <bean id="messageReader" class="org.springframework.batch.item.file.FlatFileItemReader">
        <property name="lineMapper" ref="lineMapper"/>
        <property name="resource" value="/message/user.txt"/>
    </bean>

    <bean id="lineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
        <property name="lineTokenizer" ref="lineTokenizer"/>
        <property name="fieldSetMapper" ref="fieldSetMapper"/>
    </bean>
    <bean id="fieldSetMapper" class="com.ning.demo.UserMapper"/>
    <bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"/>
    <bean id="messageProcessor" class="com.ning.demo.MessageProcessor"/>
    <bean id="messageWriter" class="com.ning.demo.MessageWriter"/>
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
Spring Batch 将批处理任务称为一个 Job,同时,Job 下分为多个 Step。Step 是一个独立的、顺序的处理步骤,包含该步骤批处理中需要的所有信息。多个批处理 Step 按照一定的流程组成一个 Job。通过这样的设计方式,我们可以灵活配置 Job 的处理过程。

     接下来的问题是如何运行构建好的BatchJob呢?SpringBatch提供了JobLauncher接口用于运行Job,并提供了一个默认的SimpleJobLauncher实现。
public class Main {
	public static void main(String[] args) {
        ClassPathXmlApplicationContext c = 
                 new ClassPathXmlApplicationContext("message_job.xml");
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository((JobRepository) c.getBean("jobRepository"));
        launcher.setTaskExecutor(new SimpleAsyncTaskExecutor());
        try {
             launcher.run((Job) c.getBean("messageJob"), new JobParameters());
        } catch (Exception e) {
        e.printStackTrace();
        }
	}
}
运行BatchJob时需要为 JobLauncher 指定一个 JobRepository,该类负责创建一个 JobExecution 对象来执行 Job,其次,需要指定一个任务执行器,我们使用 Spring Batch 提供的 SimpleAsyncTaskExecutor。最后,通过 run 方法来执行指定的 Job。运行结果如下:
Results:
TWer2,Please come to police station!
TWer5,Please come to police station!
TWer6,Please come to police station!
分享到:
评论
17 楼 dlnzs 2014-10-28  
抄袭的IBM官网的吧
http://www.ibm.com/developerworks/cn/java/j-lo-springbatch1/
16 楼 lijiejava 2014-04-01  
写的不错!
15 楼 ningandjin 2014-01-15  
引用
还是没太明白楼主的意思,是指一个Spring reader中 配置多个自定义的file reader的bean吗?但是在log目录中文件的数目是不确定的,可不可以将一整个文件夹作为数据源让SpringBatch来读取呢?
第一如果这个log的文件还有人在写,你肯定是不能读的,第二,读取未知数量的文件得自己定制,可以通过一个step获取到所有的文件,然后在下一步用Partition同时读取所有的文件。
14 楼 斌哥威武 2014-01-15  
ningandjin 写道
斌哥威武 写道

楼主!Spring Batch本身不支持多文件的读取吗?我觉得这种批处理框架应该有这种需求才对啊

SpringBatch本身带了各种Reader,怎么组合就看你自己怎么应用了,多文件读取,你写一个Reader然后里面包含多个FileReader就行就是多文件读取了,想要性能更好一点,使用Partition,每个partition一个线程,一个Reader,一个文件,实现多文件夺取的方式很多,这不能说框架不支持。

还是没太明白楼主的意思,是指一个Spring reader中 配置多个自定义的file reader的bean吗?但是在log目录中文件的数目是不确定的,可不可以将一整个文件夹作为数据源让SpringBatch来读取呢?
13 楼 ningandjin 2014-01-14  
斌哥威武 写道

楼主!Spring Batch本身不支持多文件的读取吗?我觉得这种批处理框架应该有这种需求才对啊

SpringBatch本身带了各种Reader,怎么组合就看你自己怎么应用了,多文件读取,你写一个Reader然后里面包含多个FileReader就行就是多文件读取了,想要性能更好一点,使用Partition,每个partition一个线程,一个Reader,一个文件,实现多文件夺取的方式很多,这不能说框架不支持。
12 楼 斌哥威武 2014-01-14  
ningandjin 写道
斌哥威武 写道
楼主好!有两个问题想请教一下:
1.文章的例子读取的是一个指定路径的文本,但如果我想要处理的是某个文件夹下的所有文件时该如何处理呢?比如我想读取的是一个log文件夹下的日志文件,但这些log文件的数量都是在时刻增加的
2 我可以用JobLauncher同时启动多个job吗?是不是可以获取我log目录下的所有日志文件,然后对应每个日志文件都启动一个job进行处理?
望楼主百忙之中抽空解答,小弟不 胜感激

你这个需求MapReduce貌似更好用吧, 如果实在要用Spring Batch可以看一下Spring Batch的Partition特性。http://docs.spring.io/spring-batch/reference/html/scalability.html


楼主!Spring Batch本身不支持多文件的读取吗?我觉得这种批处理框架应该有这种需求才对啊
11 楼 ningandjin 2014-01-13  
斌哥威武 写道
楼主好!有两个问题想请教一下:
1.文章的例子读取的是一个指定路径的文本,但如果我想要处理的是某个文件夹下的所有文件时该如何处理呢?比如我想读取的是一个log文件夹下的日志文件,但这些log文件的数量都是在时刻增加的
2 我可以用JobLauncher同时启动多个job吗?是不是可以获取我log目录下的所有日志文件,然后对应每个日志文件都启动一个job进行处理?
望楼主百忙之中抽空解答,小弟不 胜感激

你这个需求MapReduce貌似更好用吧, 如果实在要用Spring Batch可以看一下Spring Batch的Partition特性。http://docs.spring.io/spring-batch/reference/html/scalability.html
10 楼 斌哥威武 2014-01-13  
楼主好!有两个问题想请教一下:
1.文章的例子读取的是一个指定路径的文本,但如果我想要处理的是某个文件夹下的所有文件时该如何处理呢?比如我想读取的是一个log文件夹下的日志文件,但这些log文件的数量都是在时刻增加的
2 我可以用JobLauncher同时启动多个job吗?是不是可以获取我log目录下的所有日志文件,然后对应每个日志文件都启动一个job进行处理?
望楼主百忙之中抽空解答,小弟不 胜感激
9 楼 ningandjin 2013-11-15  
louis_zeng 写道
博主,小弟按照你写来做,不知道为何执行到
[INFO ] 2013-11-15 11:36:59 org.springframework.batch.core.launch.support.SimpleJobLauncher     Job: [FlowJob: [name=messageJob]] launched with the following parameters: [{}]
就不会执行下去了,求博主解答!万分感谢...

是否有报错信息?
8 楼 louis_zeng 2013-11-15  
博主,小弟按照你写来做,不知道为何执行到
[INFO ] 2013-11-15 11:36:59 org.springframework.batch.core.launch.support.SimpleJobLauncher     Job: [FlowJob: [name=messageJob]] launched with the following parameters: [{}]
就不会执行下去了,求博主解答!万分感谢...
7 楼 我可梦 2013-08-22  
http://s-77347.gotocdn.com/

spring batch管理平台试用环境,麻烦大家有时间,可以试用一下,提一下意见。
6 楼 我可梦 2013-08-15  
试试用spring batch管理平台吧,可以减少不少的学习时间和学习难度呢。
http://3883270.blog.51cto.com/3873270/1268540
5 楼 swanky_yao 2013-07-03  
其实你的pom文件不用写那些spring的基础包,只要加上
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
这一个就行了
他会自动下载依赖的spring核心
4 楼 ningandjin 2013-03-02  
mengfei86 写道
哥们问你个问题,springbatch中可以job中有job吗?
你为什么要job中套job呢?
3 楼 mengfei86 2013-02-20  
哥们问你个问题,springbatch中可以job中有job吗?
2 楼 ningandjin 2013-01-10  
xbyang18 写道
写的不错,我的Q:307840758可以交流交流 技术就是交流出来的

我很少上Q,新浪微博比较多。@xianlinbox
1 楼 xbyang18 2013-01-06  
写的不错,我的Q:307840758可以交流交流 技术就是交流出来的

相关推荐

    SpringBatch学习入门

    IDEA,Springbatch的入门学习资源,包括对账文件,一起学习指正,邮箱:furui-2008@163.com

    Spring.Batch批处理框架

    Spring Batch是Spring的一个子项目,使用Java语言并基于Spring框架为基础开发,使得已经使用 Spring 框架的开发者或者企业更容易访问和利用企业服务。 Spring Batch 提供了大量可重用的组件,包括了日志、追踪、事务、...

    Spring Boot整合Spring Batch,实现批处理

    Spring Boot整合Spring Batch的一个小例子,在网上发现这方面的资源比较少,特此将其上传供大家学习。

    Spring Batch API(Spring Batch 开发文档).CHM

    Spring Batch API(Spring Batch 开发文档).CHM。 官网 Spring Batch API,Spring Batch 开发文档

    Spring Batch学习demo项目源码

    Spring Batch学习过程中练习的一个简单完整的demo项目源码

    spring-batch包

    spring-batch4.0.0 batch spring-batch集成 spring-batch.jar

    SpringBatch+Spring+Mybatis+MySql (spring batch 使用jar)

    Spring Batch是一个轻量级的,完全面向Spring的批处理框架,可以应用于企业级大量的数据处理系统。Spring Batch以POJO和大家熟知的Spring框架为基础,使开发者更容易的访问和利用企业级服务。Spring Batch可以提供...

    springbatch 详解PDF附加 全书源码 压缩包

    spring batch批处理框架和对应的源码资源 rar 可以直接运行的

    The Definitive Guide to Spring Batch, 2nd Edition.epub

    Work with all aspects of batch processing in a modern Java environment using a selection of Spring frameworks. This book provides up-to-date examples using the latest configuration techniques based on...

    基于Spring Batch的大数据量并行处理

    基于Spring Batch的大数据量并行处理 基于Spring Batch的大数据量并行处理

    springBoot+springBatch批量处理数据demo

    最近在研究springBoot+springbatch ,按照官网的实例做了一个实例。 最近在研究springBoot+springbatch ,按照官网的实例做了一个实例。

    spring batch in action

    Spring Batch in Action is a comprehensive, in-depth guide to writing batch applications using Spring Batch. Written for developers who have basic knowledge of Java and the Spring lightweight ...

    spring batch 学习多种场景练习demo项目源码

    spring batch 学习多种场景练习demo项目源码,包括: 1.读取文件--处理--写入文件; 2.读取文件--处理--写入数据库 ; 3.读数据库--处理--写入数据库; 4.读数据库--处理--写入文件; 文件类型包括:CSV,TXT,JSON,XML; ...

    Spring Batch读取txt文件并写入数据库的方法教程

    主要给大家介绍了Spring Batch读取txt文件并写入数据库的方法,SpringBatch 是一个轻量级、全面的批处理框架。这里我们用它来实现文件的读取并将读取的结果作处理,处理之后再写入数据库中的功能。需要的朋友可以...

    SpringBatch-DataMigration SpringBatch数据迁移项目

    1.本项目运行在tomcat容器中,主要功能为从spring_batch_left库的user_from表抓取数据,之后批量插入到spring_batch_right库的user_to表 2.应用quartz对job进行定时触发(目前设置的定时为每隔一分钟执行一次,目前...

    详细spring batch资料

    难得的详细spring batch资料 难得的详细spring batch资料

    spring batch批处理 教程

    1,Spring Batch体系结构 4 2,Spring Batch主要对象 5 三,Spring Batch流程介绍 5 四,Spring Batch之Step执行过程介绍 6 五,Spring Batch应用 7 1,简单应用 7  构建应用 7  对象定义 7  读写及处理接口 8...

    SpringBatch数据库建表语句.txt

    SpringBatch数据库建表语句,存储springBatch批处理过程中需要保存的数据和步骤信息

    Spring Batch批处理框架

    Spring Batch批处理框架Spring Batch批处理框架Spring Batch批处理框架

    SpringBatch批处理框架

    资源名称:Spring Batch 批处理框架内容简介:《Spring Batch 批处理框架》全面、系统地介绍了批处理框架Spring Batch,通过详尽的实战示例向读者展示了Spring Batch框架对大数据批处理的基本开发能力,并对框架的...

Global site tag (gtag.js) - Google Analytics