zoukankan      html  css  js  c++  java
  • springbatch---->springbatch的使用(七)

      这里我们讲述一下springbatch中关于step层面上面的数据共享技术。而对街的人影都浸染在一片薄荷的白色中,由于无声,都好像经过漂染,不沾人间烟火。

    step的数据共享

      关于springbatch里面的step的数据共享,可以有很多的实现方式。比如可以用数据库记载共享的数据、文件保存共享的数据等等。这里我们重点讨论的是springbatch与spring可以解决这类问题的方案。总的来说,可以有如下两种方式。

    Execution context
        Use a Spring Batch execution context as a container for user data. A step writes to the execution context; then another step reads from the execution context.
    Holder 
        Use a Spring bean and dependency injection. Spring injects a holder bean in the communicating beans. A first step sets values in the holder; another step reads values from the holder.

    下面我们针对这同种方式做一个测试的案例。

    一、使用Execution context方式共享数据

    • 定义一个job,在batch.xml里面
    <job id="shareDataContextJob">
        <step id="setDateStep" next="getDateStep">
            <tasklet transaction-manager="transactionManager" ref="setDataContextTasklet"/>
        </step>
        <step id="getDateStep">
            <tasklet transaction-manager="transactionManager" ref="getDataContextTasklet"/>
        </step>
    </job>
    • setDataContextTasklet与getDataContextTasklet的定义
    <bean id="setDataContextTasklet" class="spring.batch.shareDataContext.SetDataContextTasklet"/>
    <bean id="getDataContextTasklet" class="spring.batch.shareDataContext.GetDataContextTasklet"/>
    • setDataContextTasklet与getDataContextTasklet的实现

    存放数据的实现类

    package spring.batch.shareDataContext;
    
    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.item.ExecutionContext;
    import org.springframework.batch.repeat.RepeatStatus;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-02 下午 8:41
     */
    public class SetDataContextTasklet implements Tasklet {
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            ExecutionContext jobExecutionContext = chunkContext.getStepContext().
                            getStepExecution().
                            getJobExecution().
                            getExecutionContext();
            jobExecutionContext.putString("username", "huhx");
            System.out.println("set data tasklet.");
            return RepeatStatus.FINISHED;
        }
    }

    得到数据的实现类

    package spring.batch.shareDataContext;
    
    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.item.ExecutionContext;
    import org.springframework.batch.repeat.RepeatStatus;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-02 下午 8:41
     */
    public class GetDataContextTasklet implements Tasklet {
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            ExecutionContext jobExecutionContext = chunkContext.getStepContext().
                    getStepExecution().
                    getJobExecution().
                    getExecutionContext();
            String username = jobExecutionContext.getString("username");
            System.out.println("username = " + username);
            return RepeatStatus.FINISHED;
        }
    }

    运行的结果,setDateStep得到的getDateStep存放的数据。

    set data tasklet.
    username = huhx

    另外我们还有另外一种写法。在基于上述的代码做如下的修改:getDataContextTasklet和定义与实现。注意scope="step"是必须的。

    <bean id="getDataContextTasklet" class="spring.batch.shareDataContext.GetDataContextTasklet" scope="step">
        <property name="username" value="#{jobExecutionContext['username']}"/>
    </bean>

     getDataContextTasklet的实现类,可以直接注入username得到setDataContextTasklet里面设置的username值。

    package spring.batch.shareDataContext;
    
    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.item.ExecutionContext;
    import org.springframework.batch.repeat.RepeatStatus;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-02 下午 8:41
     */
    public class GetDataContextTasklet implements Tasklet {
        private String username;
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            System.out.println("username = " + username);
            return RepeatStatus.FINISHED;
        }
    }

    二、通过Spring holder beans共享数据

    • 定义一个job,在batch.xml中
    <job id="shareDataHolderJob">
        <step id="setDateHolderStep" next="getDateHolderStep">
            <tasklet transaction-manager="transactionManager" ref="setDataHolderTasklet"/>
        </step>
        <step id="getDateHolderStep">
            <tasklet transaction-manager="transactionManager" ref="getDataHolderTasklet"/>
        </step>
    </job>
    • setDataHolderTasklet、getDataHolderTasklet以及共享数据Bean类的定义
    <!--通过holder分享数据-->
    <bean id="importMetadata" class="spring.batch.shareDataHolder.ImportMetadataHolder"/>
    <bean id="setDataHolderTasklet" class="spring.batch.shareDataHolder.SetDataHolderTasklet"> <property name="importMetadataHolder" ref="importMetadata"/> </bean> <bean id="getDataHolderTasklet" class="spring.batch.shareDataHolder.GetDataHolderTasklet"> <property name="importMetadataHolder" ref="importMetadata"/> </bean>
    • 上述xml定义的bean类的实现

    ImportMetadataHolder:共享数据Bean类。

    package spring.batch.shareDataHolder;
    
    import spring.batch.readFile.People;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-03 上午 8:56
     */
    public class ImportMetadataHolder {
        private People people;
    
        public People getPeople() {
            return people;
        }
    
        public void setPeople(People people) {
            this.people = people;
        }
    }

    SetDataHolderTasklet:设置共享数据的实现类

    package spring.batch.shareDataHolder;
    
    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;
    import spring.batch.readFile.People;
    
    import java.util.Date;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-03 上午 9:00
     */
    public class SetDataHolderTasklet implements Tasklet {
        private ImportMetadataHolder importMetadataHolder;
    
        public void setImportMetadataHolder(ImportMetadataHolder importMetadataHolder) {
            this.importMetadataHolder = importMetadataHolder;
        }
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            People people = new People();
            people.setUsername("huhx");
            people.setBirthday(new Date());
            people.setAddress("武汉");
            people.setAge(23);
            importMetadataHolder.setPeople(people);
            return RepeatStatus.FINISHED;
        }
    }

    GetDataHolderTasklet:获取共享数据的实现类

    package spring.batch.shareDataHolder;
    
    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;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-03 上午 9:00
     */
    public class GetDataHolderTasklet implements Tasklet {
        private ImportMetadataHolder importMetadataHolder;
    
        public void setImportMetadataHolder(ImportMetadataHolder importMetadataHolder) {
            this.importMetadataHolder = importMetadataHolder;
        }
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            System.out.println(importMetadataHolder.getPeople());
            return RepeatStatus.FINISHED;
        }
    }

    运行的结果,在控制台打印:

    username=huhx|age=23|address=武汉|birthday=Fri Nov 03 09:06:24 CST 2017

    之所以ImportMetadataHolder类能够共享,是由于spring中Bean的默认scope是singleton单例的。如果修改scope为prototype。那么输出的结果为null。

    另外这种方式也可以使用SpEL表达式的方式来注入要共享的数据。修改getDataHolderTasklet的定义和实现类以及修改importMetadata的scope=singleton。如下

    <bean id="getDataHolderTasklet" class="spring.batch.shareDataHolder.GetDataHolderTasklet" scope="step">
        <property name="username" value="#{importMetadata.getPeople().getUsername()}"/>
    </bean>

    GetDataHolderTasklet可以直接注入username,打印它的结果为huhx。这里就不贴出代码。

    友情链接

  • 相关阅读:
    一款HTML5网页网络检测工具--LibreSpeed
    远程连接Linux中的Mysql数据库
    Ubuntu安装python-rrdtool模块
    Ubuntu 18.04 lxd和lxd-client导致版本过低无法apt安装
    7.JVM调优-方法区,堆,栈调优详解
    6.堆和GC
    5.java内存模型详细解析
    4.自定义类加载器实现及在tomcat中的应用
    3.代码实现自定义类加载器
    2.双亲委派机制详细解析及原理
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusespringbatch7.html
Copyright © 2011-2022 走看看