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

      这里我们重点学习一下springbatch里面的各种监听器的使用,以及job参数的传递。追求得到之日即其终止之时,寻觅的过程亦即失去的过程。

    springbatch的监听器

    一、JOB LISTENERS:监听job层面上的操作

    public interface JobExecutionListener {
        void beforeJob(JobExecution jobExecution);
        void afterJob(JobExecution jobExecution);
    }
    • 类方法的方式
    <job id="helloWorldJob">
        <listeners>
            <listener ref="jobExecListener"/>
        </listeners>
        <step ....>
        </step>
    </job>

    bean的定义

    <bean id="jobExecListener" class="spring.batch.helloworld.JobExecListener"/>

     bean的实现

    package spring.batch.helloworld;
    
    import org.springframework.batch.core.JobExecution;
    import org.springframework.batch.core.JobExecutionListener;
    
    /**
     * @Author: huhx
     * @Date: 2017-11-02 上午 8:50
     */
    public class JobExecListener implements JobExecutionListener {
    
        @Override
        public void beforeJob(JobExecution jobExecution) {
            System.out.println("before start time: " + jobExecution.getStartTime());
        }
    
        @Override
        public void afterJob(JobExecution jobExecution) {
            System.out.println("after end time: " + jobExecution.getEndTime());
        }
    }
    • 使用注解方式,区别在于bean类的编写。
    public class JobExecListener {
    
        @BeforeJob
        public void beforeJob(JobExecution jobExecution) {
            System.out.println("before start time: " + jobExecution.getStartTime());
        }
    
        @AfterJob
        public void afterJob(JobExecution jobExecution) {
            System.out.println("after end time: " + jobExecution.getEndTime());
        }
    }

    这个例子是基于helloworld的例子来的,可以参考博客:springbatch---->springbatch的使用(一).。以下是打印的结果

    before start time: Thu Nov 02 09:00:13 CST 2017
    Hello 
     World!
    after end time: Thu Nov 02 09:00:14 CST 2017

    二、STEP LISTENERS:监听Step的处理过程

    springbatch为我们提供了如下的关于Step的监听器。

    1、ChunkListener 
        Called before and after chunk execution
    2、ItemProcessListener 
        Called before and after an ItemProcessor gets an item and when that processor throws an exception
    3、ItemReadListener 
        Called before and after an item is read and when an
    exception occurs reading an item
    4、ItemWriteListener 
        Called before and after an item is written and when an exception occurs writing an item
    5、SkipListener 
        Called when a skip occurs while reading, processing, or writing an item
    6、StepExecutionListener 
        Called before and after a step

    Step监听器的接口,用法同上述的Job监听器基本一样。也是有方法的实现方式和注解的实现方式。

    三、parent与abstract属性的使用

    1、abstract 
        When  true, specifies that the job or step element isn’t a concrete element but an abstract one used only for configuration. Abstract configuration enti-
    ties aren’t instantiated.
    2、parent: 子元素继承了父元素所有的属性,当然子元素可以复写父元素的属性
        The parent element used to configure a given element. The child element has all properties of its parent and can override them.

     在batch.xml文件中增加一个step和一个job。

    <!--parent and abstract-->
    <step id="parentStep" abstract="true">
        <tasklet transaction-manager="transactionManager">
            <listeners>
                <listener ref="parentStepListener"/>
            </listeners>
        </tasklet>
    </step>
    
    <job id="childJob">
        <step id="childStep" parent="parentStep">
            <tasklet ref="childTasklet" transaction-manager="transactionManager"/>
        </step>
    </job>
    
    <bean:bean id="childTasklet" class="spring.batch.parentAbstract.ParentTasklet" scope="step">
        <bean:property name="username" value="#{jobParameters['password']}"/>
    </bean:bean>

      parentTasklet的实现类代码:

    package spring.batch.parentAbstract;
    
    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-02 上午 9:18
     */
    public class ParentTasklet 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("parent tasklet" + username);
            return RepeatStatus.FINISHED;
        }
    }

    打印的结果如下,可以看到childJob已经有了parentStep里面的监听器了。

    before step.
    parent tasklet123456
    after step.

     另外JobLaunch.java的代码如下

    public class JobLaunch {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("config/batch/batch.xml");
            JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
    
            Job job = (Job) context.getBean("childJob");
            try {
                // 运行Job
                JobParametersBuilder parametersBuilder = new JobParametersBuilder();
                JobParameters jobParameters = parametersBuilder.
                        addString("username", "linux").
                        addString("password", "123456").
                        toJobParameters();
                launcher.run(job, jobParameters);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    有关于scope="step" 的解释,这里说明一下。

        The step scope means that Spring will create the bean only when the step asks for it and that values will be resolved then (this is the lazy instantiation pattern; the bean isn’t created during the Spring application context’s bootstrapping). To trigger the dynamic evaluation of a value, you must use the #{expression} syntax. The expression must be in Sp EL , which is available as of Spring 3.0.

    四、关于ValidatingItemProcessor的一些理解

      它实现了ItemProcessor,用于chunk里面的processor属性。以下是它的一个用法。Simple implementation of ItemProcessor that validates input and returns it without modifications.

    ...
    <batch:chunk reader="reader" processor="processor" writer="writer" commit-interval="100" skip-limit="5">
        <batch:skippable-exception-classes>
            <batch:include class="org.springframework.batch.item.validator.ValidationException"/>
        </batch:skippable-exception-classes>
    </batch:chunk>
    ....
    
    <bean id="processor" class="org.springframework.batch.item.validator.ValidatingItemProcessor">
        <property name="filter" value="false" />
        <property name="validator">
            <bean class="spring.batch.parentAbstract.ProductValidator" />
        </property>
    </bean>

    ProductValidator的代码

    import java.math.BigDecimal;
    import org.springframework.batch.item.validator.ValidationException;
    import org.springframework.batch.item.validator.Validator;
    import com.manning.sbia.ch01.domain.Product;
    
    public class ProductValidator implements Validator<Product> {
        @Override
        public void validate(Product product) throws ValidationException {
            if(BigDecimal.ZERO.compareTo(product.getPrice()) >= 0) {
                throw new ValidationException("Product price cannot be negative!");
            }
        }
    }

    关于ValidatingItemProcessor的源代码,它有两个属性validator和filter 。

    package org.springframework.batch.item.validator;
    
    import org.springframework.batch.item.ItemProcessor;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.util.Assert;
    
    public class ValidatingItemProcessor<T> implements ItemProcessor<T, T>, InitializingBean {
    
        private Validator<? super T> validator;
    
        private boolean filter = false;
    
        public ValidatingItemProcessor() {}
    
        public ValidatingItemProcessor(Validator<? super T> validator) {
            this.validator = validator;
        }
    
        public void setValidator(Validator<? super T> validator) {
            this.validator = validator;
        }
    
        public void setFilter(boolean filter) {
            this.filter = filter;
        }
    
        @Override
        public T process(T item) throws ValidationException {
            try {
                validator.validate(item);
            }
            catch (ValidationException e) {
                if (filter) {
                    return null; // filter the item
                }
                else {
                    throw e; // skip the item
                }
            }
            return item;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            Assert.notNull(validator, "Validator must not be null.");
        }
    }

    友情链接

  • 相关阅读:
    数学是最好的语言
    人类的语言--自然语言--》逻辑语言
    为什么大脑喜欢看图?
    思考是调用大脑存储的上下文对输入信息进行处理的过程
    Redis的相关问题总结
    TP5 关联模型使用(嵌套关联、动态排序以及隐藏字段)
    array_column 函数, 以及在PHP5.5之下的替代方法
    thinkphp在app接口开发过程中的通讯安全认证
    PHP开发APP接口实现--基本篇
    分布式与集群的区别是什么?
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusespringbatch4.html
Copyright © 2011-2022 走看看