Spring Batch 批处理-作业监听器

news2024/11/24 7:37:05

引言

接着上篇:Spring Batch 批处理-作业增量参数,了解作业参数增量器后,本篇就来了解一下Spirng Batch 作业监听器,看能玩出啥花样。

作业监听器

Spring Batch 步骤/作业的设计延续Spring传统设计模式,加入生命周期的概念,也就是说,步骤/作业也有执行前,执行中,执行后3个时间概念

  • 执行前:一般用于初始化操作, 步骤/作业执行前需要着手准备工作,比如:各种连接建立,线程池初始化等。

  • 执行中:步骤/业务操作业务逻辑

  • 执行后:步骤/业务执行完后,需要做各种清理动作,比如释放资源等。

Spring Batch 引入监听器的概念来实现生命周期逻辑,JobExecutionListener接口监听作业的生命周期,StepListener接口实现步骤的生命周期,当前先讲作业的监听器JobExecutionListener,后面Step对象章节我们再讲StepListener

public interface JobExecutionListener {
    //作业执行前
	void beforeJob(JobExecution jobExecution);
    //作业执行后
	void afterJob(JobExecution jobExecution);
}

需求:记录作业执行前,执行中,与执行后的状态

方式一:接口方式

//作业状态--接口方式
public class JobStateListener  implements JobExecutionListener {
    //作业执行前
    @Override
    public void beforeJob(JobExecution jobExecution) {
        System.err.println("执行前-status:" + jobExecution.getStatus());
    }
    //作业执行后
    @Override
    public void afterJob(JobExecution jobExecution) {
        System.err.println("执行后-status:" + jobExecution.getStatus());
    }
}

定义JobStateListener 实现JobExecutionListener 接口,重写beforeJob,afterJob 2个方法。


import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableBatchProcessing
public class StatusListenerJob {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Tasklet tasklet(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                JobExecution jobExecution = contribution.getStepExecution().getJobExecution();
                System.err.println("执行中-status:" + jobExecution.getStatus());
                return RepeatStatus.FINISHED;
            }
        };
    }

    //状态监听器
    @Bean
    public JobStateListener jobStateListener(){
        return new JobStateListener();
    }

    @Bean
    public Step  step1(){
        return  stepBuilderFactory.get("step1")
                .tasklet(tasklet())
                .build();
    }
    @Bean
    public Job job(){
        return jobBuilderFactory.get("status-listener-job")
                .start(step1())
                .listener(jobStateListener())  //设置状态监听器
                .build();
    }
    public static void main(String[] args) {
        SpringApplication.run(StatusListenerJob.class, args);
    }
}

新加jobStateListener()实例方法创建对象交个Spring容器管理,修改job()方法,添加.listener(jobStateListener()) 状态监听器,直接执行,观察结果

方式二:注解方式

 除去上面通过实现接口方式实现监听之外,也可以使用@BeforeJob @AfterJob 2个注解实现

//作业状态--注解方式
public class JobStateAnnoListener  {
    @BeforeJob
    public void beforeJob(JobExecution jobExecution) {
        System.err.println("执行前-anno-status:" + jobExecution.getStatus());
    }

    @AfterJob
    public void afterJob(JobExecution jobExecution) {
        System.err.println("执行后-anno-status:" + jobExecution.getStatus());
    }
}

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.listener.JobListenerFactoryBean;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableBatchProcessing
public class StatusListenerJob {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Tasklet tasklet(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                JobExecution jobExecution = contribution.getStepExecution().getJobExecution();
                System.err.println("执行中-anno-status:" + jobExecution.getStatus());
                return RepeatStatus.FINISHED;
            }
        };
    }

    //状态监听器
/*    @Bean
    public JobStateListener jobStateListener(){
        return new JobStateListener();
    }*/

    @Bean
    public Step  step1(){
        return  stepBuilderFactory.get("step1")
                .tasklet(tasklet())
                .build();
    }
    @Bean
    public Job job(){
        return jobBuilderFactory.get("status-listener-job1")
                .start(step1())
                .incrementer(new RunIdIncrementer())
                //.listener(jobStateListener())  //设置状态监听器
                .listener(JobListenerFactoryBean.getListener(new JobStateAnnoListener()))
                .build();
    }
    public static void main(String[] args) {
        SpringApplication.run(StatusListenerJob.class, args);
    }
}

修改job()方法,添加.listener(JobListenerFactoryBean.getListener(new JobStateAnnoListener()))状态监听器,直接执行,观察结果

不需要纠结那一长串方法是啥逻辑,只需要知道它能将指定监听器对象加载到spring容器中。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「Electron|快速开始」来写个Hello World桌面应用吧

本文主要介绍如何快速使用Electron生成一个Hello World应用 文章目录主要步骤一、准备工作创建项目安装electron二、编写electron应用所需的基本内容首先,我们需要给electron应用一个入口创建窗口往窗口里面放一个HTML界面,写上"Hello World!"…

计算机网络技术-常见网络命令

文档下载:https://download.csdn.net/download/weixin_57836618/87294136 实验2 常见网络命令 1. 实验目的与意义 ① 通过实验熟悉与网络相关的组件的含义和用途。 ② 了解系统网络命令的含义、用途和操作方法。 ③ 能够查看网络的状态,对网络进行简…

DEiT实战:使用DEiT实现图像分类任务(一)

DEiT实战摘要安装包安装timm数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集摘要 DEiT是FaceBook在2020年提出的一篇Transformer模型。该模型解决了Transformer难以训练的问题,三天内使用4块GPU,完成了ImageNet的训练,并且没有使用…

mPEG-N3;mPEG-Azide;甲氧基聚乙二醇叠氮CAS:89485-61-0

叠氮化物/叠氮基官能化的甲氧基聚乙二醇(mPEG-N3)是一种单官能PEG衍生物,可用于修饰蛋白质,肽和其他材料。 叠氮化物基团可以在铜催化的水溶液中与炔烃反应。 也可以容易地还原成胺基。 名称 甲氧基聚乙二醇叠氮 mPEG-N3 别称 甲…

周志华 《机器学习初步》模型评估与选择

周志华 《机器学习初步》模型评估与选择 Datawhale2022年12月组队学习 ✌ 文章目录周志华 《机器学习初步》模型评估与选择一.泛化能力二.过拟合和欠拟合泛化误差 VS 经验误差过拟合 VS 欠拟合三.模型选择的三大问题如何获得测试结果:评估方法如何评估性能优劣&…

工厂设备管理中经常会遇到哪些问题?

我调查过上百家企业的设备管理问题,发现大家认为所有设备管理问题中,最典型的问题主要包括以下五个方面: 1)领导不重视管理 “生产量是最重要的”、“销售额是最重要”、“重ERP,轻现场管理”……等管理理念是企业中的…

镜像法的理解——工程电磁场 P9

模型一:无限大导体平面 此处有几点理解需要格外谈一下 1. 只有在有电力线的地方,才会产生电场的作用 2.对于下平面的分析,下平面如果存在电荷的话,必然存在电力线,那么从无穷远处做功到此处,必然会存在电…

Java网络多线程——UDP编程

UDP编程通信 基本介绍 类DatagramSocket和DatagramPacket【数据包/数据报】实现了基于UDP协议网络程序。UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能安全送到目的地,也不确信什么时候可以抵达。DatagramPacket对象封…

从「堆叠」到「降本」,智能汽车传感器颠覆性革命即将到来!

随着汽车智能化的演进,传感器的堆叠造成了整车成本的急剧上升。尤其是多传感器融合(摄像头、毫米波雷达和激光雷达)技术作为当下的主流趋势之一,焦点依然回到成本层面。 同时,传统的整车电子架构和计算能力的限制&…

Flutter 小技巧之快速理解手势逻辑

又到了小技巧系列更新时间,今天我们主要分享 Flutter 里的手势触摸逻辑,其实在很久之前我就写过 《面深入触摸和滑动原理》相关的源码分析文章,但是最近有人说源码分析看不懂,有没有简要好理解的,那么本篇就用更简单的…

[附源码]Node.js计算机毕业设计高校图书馆网站Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

高通平台 5G RF调试总结

目录: 1.QRCT4的使用 2.RFC配置 3.5G CA 配置概括 4.RFPD 运行及错误分析 5.CA吞吐率问题分析 最新的5G HImalyaa平台RFC的配置方法和之前的平台发生了根本性的变化,主要体现在使用QRCT4工具来配置RFC XML文件,然后根据XML文件编译生成s…

MobileNetV3原理说明及实践落地

本文参考: pytorch实现并训练MobileNetV3 - 灰信网(软件开发博客聚合) 【神经网络】(16) MobileNetV3 代码复现,网络解析,附Tensorflow完整代码 - 代码天地 1 MobileNetV3与V1、V2对比 (1)Mob…

【LeetCode每日一题:1945. 字符串转化后的各位数字之和~~~模拟】

题目描述 给你一个由小写字母组成的字符串 s ,以及一个整数 k 。 首先,用字母在字母表中的位置替换该字母,将 s 转化 为一个整数(也就是,‘a’ 用 1 替换,‘b’ 用 2 替换,… ‘z’ 用 26 替换…

匿名浏览器是什么?为什么联盟营销需要借助匿名浏览器?

这段时间小伙伴们都对联盟营销很感兴趣,东哥也是陆陆续续出了两三篇相关的科普文章,今天继续给大家介绍匿名浏览器在联盟营销上的帮助,毕竟互联网时代,学会如何借助工具高效工作是很重要的。关于联盟营销的概念科普文章大家可以看…

学不会的python之通过某几个关键字排序、分组一个字典列表(列表中嵌套字典)

通过某个关键字排序、分组一个字典列表排序问题描述解决方案1.operator 模块的 itemgetter 函数2.lambda 表达式引申分组问题描述解决方案1.itertools.groupby() 函数2.defaultdict() 构建多值字典排序 问题描述 现在你有一个字典列表(列表中嵌套字典),你想要根据…

web 向 unity 传输文件流 blob 记录

场景:web 与unity 通信,向 unity 传输文件 二进制流。 由 unity 转换并下载文件。 流程: web 端将缓存的 blob 数据流读取为 base64 编码的数据 → 传给 unity, →unity 解码转换 base64 数据并下载。 web 端: 1、 将数据转换成…

【Axure教程】自定义审批流原型模板

审批流即审批流程,是对某项工作的审批活动的一系列有序组合。审批流在业务系统中担当者非常重要的角色,所以今天作者就教大家制作一个通用的自定也审批流的原型模板,方便大家日后的工作。 一、效果展示 1、可以根据业务需要添加多个审批节点…

QT学习笔记(中)

QT学习笔记(中) 文章目录QT学习笔记(中)P21 消息对话框P22 其他标准对话框P23 登录窗口界面和布局P24 控件 按钮组P25 QListWidget控件P26 QTreeWidget控件的使用P27 tableWidgetP28 其他常用控件介绍P30 自定义控件P31 QEventP32…

PyQt5 QtChart-折线图

PyQt5 QtChart-QLineSeries 折线图QLineSeriesQLineSeries QLineSeries类将数据序列显示为折线图,其核心代码: lineSeries QLineSeries() lineSeries.append(1, 3) lineSeries.append(5, 8) … chart.addSeries(lineSeries) 常用方法: set…