zoukankan      html  css  js  c++  java
  • Spring Batch:入门

    简介

    ​ 企业域内的许多应用程序都需要批量处理才能在关键任务环境中执行业务操作。这些业务操作包括自动化,复杂的海量信息处理,无需用户交互即可最有效地进行处理。这些操作通常包括基于时间的事件(例如,月末计算,通知或通信),周期性应用非常大的数据集重复处理的复杂业务规则(例如,保险利益确定或费率调整)或所接收信息的集成从通常需要以事务处理方式进行格式化,验证和处理的内部和外部系统进入记录系统。批处理每天用于为企业处理数十亿笔事务。

    Spring Batch 是一个轻量级的,全面的批处理框架,旨在支持开发对企业系统的日常运行至关重要的强大的批处理应用程序。

    Spring Batch 不是一个调度框架。商业和开放源代码空间(例如 Quartz,Tivoli,Control-M 等)中都有许多好的企业调度程序。它旨在与调度程序结合使用,而不是替换调度程序。

    Spring Batch 实现的特性包括数据验证、格式化输出、轶可重用的方式实现复杂逻辑以及处理大数据的能力。

    Spring Batch架构

    如下图所示:Spring Batch的分层配置由三层组成。

    image-20210625235118700

    Application:应用层,包括所有用来构建批处理的定制化代码和配置。业务逻辑、服务以及组织任务的配置等,都是应用层所关心的内容。应用层不不是在其他两层之上,而是封装了其他两层。

    Batch Core:核心层,包含用于定义批处理域的所有部分。核心组件的元素包括作业(Job)和步骤(Step)接口,以及用来执行作业的如下两个接口:JobLauncher和JobParameters。

    Batch Infrastructure:基础设施层,在处理任何东西前,都需要读取或写入文件、数据等。在任务失败后,必须能够进行重试,这些部分被认为是一些通用的基础设施。

    初体验

    创建工程:pom依赖

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-batch</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.batch</groupId>
                <artifactId>spring-batch-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    

    主启动类:

    @EnableBatchProcessing
    @SpringBootApplication
    public class BootBatchApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BootBatchApplication.class, args);
        }
    
        @Autowired
        private JobBuilderFactory jobBuilderFactory;
    
        @Autowired
        private StepBuilderFactory stepBuilderFactory;
    
        @Bean
        public Step step() {
            return this.stepBuilderFactory.get("step1")
                    .tasklet(new Tasklet() {
                        @Override
                        public RepeatStatus execute(StepContribution contribution,
                                                    ChunkContext chunkContext) {
                            System.out.println("Hello, World!");
                            return RepeatStatus.FINISHED;
                        }
                    }).build();
        }
    
        @Bean
        public Job job() {
            return this.jobBuilderFactory.get("job")
                    .start(step())
                    .build();
        }
    
    }
    

    运行结果:

    image-20210626001126986

    分析

    @EnableBatchProcessing

    进入该注解:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(BatchConfigurationSelector.class)
    public @interface EnableBatchProcessing {
    
    	boolean modular() default false;
    
    }
    

    该注解import了另一个组件BatchConfigurationSelector,该类实现了ImportSelector接口,熟悉Spring的应该知道,通过该接口批量注册组件

    public class BatchConfigurationSelector implements ImportSelector {
    
    	@Override
    	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    		Class<?> annotationType = EnableBatchProcessing.class;
    		AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
    				annotationType.getName(), false));
    		Assert.notNull(attributes, String.format("@%s is not present on importing class '%s' as expected",
    				annotationType.getSimpleName(), importingClassMetadata.getClassName()));
    
    		String[] imports;
    		if (attributes.containsKey("modular") && attributes.getBoolean("modular")) {
    			imports = new String[] { ModularBatchConfiguration.class.getName() };
    		}
    		else {
    			imports = new String[] { SimpleBatchConfiguration.class.getName() };
    		}
    
    		return imports;
    	}
    
    }
    

    EnableBatchProcessing注解的modular方法默认返回false,通过BatchConfigurationSelector,不难看出,该类会向IOC容器中添加一个SimpleBatchConfiguration配置类。

    该配置类又向容器中添加了一下几个组件:

    • JobRepository 记录作业运行时的状态
    • JobLauncher 启动作业
    • JobRegistry 在使用特定的启动器实现时找到作业
    • JobExplorer 使用JobRepository 执行只读操作
    • PlatformTransactionManager 在工作过程中处理事务

    下面两个bean在SimpleBatchConfiguration的父类AbstractBatchConfiguration中定义的

    • JobBuilderFactory 作业构建工厂
    • StepBuilderFactory 步骤构建工厂

    因为在EnableBatchProcessing中向容器添加了JobBuilderFactory 和StepBuilderFactory ,所以我们想要使用,就可以直接@Autowired了。

    并且通过他们来创建我们自定义的JobStep

    那么上述的Job是怎么运行的呢?

    在SpringBatch中有一个组件JobLauncherApplicationRunner,实现了ApplicationRunner接口,在SpringBoot容器启动时,会调用所有的ApplicationRunner接口的run方法

    image-20210626003922308

    execute后续就不往下看了。

  • 相关阅读:
    Visual Studio使用Git忽略不想上传到远程仓库的文件
    使用git处理github中提交有冲突的pull request
    C#基础访问修饰符概述
    从代码角度理解NNLM(A Neural Probabilistic Language Model)
    命名实体识别数据预处理
    基于bert命名实体识别(一)数据处理
    transformer多头注意力的不同框架实现(tensorflow+pytorch)
    基于tensorflow的bilstm_crf的命名实体识别(数据集是msra命名实体识别数据集)
    python实现命名实体识别指标(实体级别)
    基于tensorflow的文本分类总结(数据集是复旦中文语料)
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/14933211.html
Copyright © 2011-2022 走看看