Spring Batch之命令行执行Job(九)

        Spring Batch提供通过命令行的方式执行Job的功能,通过命令行的方式可以在一个单独的JVM中执行批量处理作业。通过命令行的方式可以手动触发,也可以定义自动任务通过脚本的方式执行批处理作业。Spring Batch框架提供的命令行执行类:org.springframework.batch.core.launch.support.CommandLineJobRunner.

CommandLineJobRunner参数说明如下:

java -classpath “xxx” CommandLineJobRunner jobPath <options> jobIdentifier(jobParameters)

  • jobPath:CommandLineJobRunner默认使用ClassPathXmlApplicationContext从当前的classpath中加载配置文件。
  • options:可选的参数,支持参数包括-restart、-stop、-abandon、-next。

        -restart      根据jobIdentifier重启最后一次失败的作业

        -stop          根据jobIdentifier停止正在执行的作业

        -abandon   根据jobIdentifier废弃stopped的作业

        -next          根据JobParametersIncrementer执行下一个作业

  • jobIdentifier:作业的名字,即Spring配置文件中配置的Job的Bean ID,或者是job execution的id(当使用-restart、-stop、-abandon时候,需要传入job execution的id)。
  • job Parameters:作业参数可以有0到多个,其支持的类型为String,Date,Long,Double。

一、项目架构

   

二、代码实现

CreditBill.java:

package com.xj.demo8;

/**
 * @Author : xjfu
 * @Date : 2021/12/05 19:27
 * @Description :demo8的CreditBill
 */
public class CreditBill {
    //银行卡账户ID
    private String accountID = "";
    //持卡人姓名
    private String name = "";
    //消费金额
    private double amount = 0;
    //消费日期
    private String date = "";
    //消费场所
    private String address = "";

   
    get和set方法....
}

CreditBillProcessor.java:

package com.xj.demo8;

import org.springframework.batch.item.ItemProcessor;

/**
 * @Author : xjfu
 * @Date : 2021/12/05 19:29
 * @Description :demo8的处理类
 */
public class CreditBillProcessor implements ItemProcessor<CreditBill, CreditBill> {
    @Override
    public CreditBill process(CreditBill bill) throws Exception {

        System.out.println(bill.toString());
        //做一些简单的处理
        bill.setAccountID(bill.getAccountID() + "1");
        bill.setName(bill.getName() + "2");
        bill.setAmount(bill.getAmount() + 3);
        bill.setDate(bill.getDate() + "4");
        bill.setAddress(bill.getAddress() + 5);

        return bill;
    }
}

demo8-inputFile.csv:

4101231234656,tom,100.00,2013-12-31 12:00:08,Lu lit
4101236543210,tom,120.00,2013-12-31 12:00:08,Lu Zui

demo8-inputFile2.csv:

4101231234656,Junne,100.00,2013-12-31 24:00:08,Lu lit
4101236543210,Junne,120.00,2013-12-31 24:00:08,Lu Zui

demo8-job.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">

    <!--导入文件-->
    <import resource="classpath:demo8/job/demo8-jobContext.xml"/>

    <!--定义名字为billJob的作业-->
    <batch:job id="billJob">
        <!--定义名字为billStep的作业步-->
        <batch:step id="billStep">
            <batch:tasklet transaction-manager="transactionManager">
                <!--定义读、处理、写操作,规定每处理两条数据,进行一次写入操作,这样可以提高写的效率-->
                <batch:chunk reader="csvItemReader" processor="creditBillProcessor" writer="csvItemWriter"   commit-interval="2">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>
</beans>

demo8-jobContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">

    <!--定义作业仓库 Job执行期间的元数据存储在内存中-->
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>

    <!--定义作业调度器,用来启动job-->
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <!--注入jobRepository-->
        <property name="jobRepository" ref="jobRepository"/>
    </bean>

    <!--定义事务管理器,用于Spring Batch框架中对数据操作提供事务能力-->
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>

    <!--读取信用卡账单文件,CSV 格式-->
    <!--使用FlatFileItemReader读文本文件-->
    <bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
        <!--指定读取的资源文件-->
        <property name="resource" value="classpath:demo8/data/demo8-inputFile.csv"/>
        <!--通过lineMapper把文本中的一行转换为领域对象creditBill-->
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <!--lineTokenizer定义文本中每行的分隔符号-->
                <property name="lineTokenizer" ref="lineTokenizer"/>
                <!--fieldSetMapper定义了转换结果映射,即具体映射到哪个Java类对象-->
                <property name="fieldSetMapper">
                    <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="prototypeBeanName" value="creditBill"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!--lineTokenizer-->
    <bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
        <!--按","符号对行进行切割-->
        <property name="delimiter" value=","/>
        <!--属性名称列表,将切割后的行按顺序投入-->
        <property name="names">
            <list>
                <value>accountID</value>
                <value>name</value>
                <value>amount</value>
                <value>date</value>
                <value>address</value>
            </list>
        </property>
    </bean>

    <!--注入实体类-->
    <bean id="creditBill" class="com.xj.demo8.CreditBill" scope="prototype"></bean>

    <!--数据处理类-->
    <bean id="creditBillProcessor" class="com.xj.demo8.CreditBillProcessor" scope="step"></bean>

    <!--写信用卡账单文件,CSV格式-->
    <bean id="csvItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
        <!--要写入的文件位置,因为[classpath:]不是一个具体的目录,这里应当用[file:](从项目根目录开始)指明输出位置-->
        <property name="resource" value="file:src/main/resources/demo8/data/demo8-outputFile.csv"/>
        <!--[lineAggregator成员]指明行聚合器,用来将对象输出到文件时构造文件中的每行的格式-->
        <property name="lineAggregator">
            <!--这里使用Spring Batch自带的DelimitedLineAggregator来作为行聚合器(可以拼接一个个属性形成行)-->
            <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                <!--使用","拼接-->
                <property name="delimiter" value=","/>
                <!--fieldExtractor成员用来将Java类的属性组成的数组拼接成行字符串-->
                <property name="fieldExtractor">
                    <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <property name="names" value="accountID,name,amount,date,address">
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
</beans>

demo8-jobContext2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">

    <!--定义作业仓库 Job执行期间的元数据存储在内存中-->
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>

    <!--定义作业调度器,用来启动job-->
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <!--注入jobRepository-->
        <property name="jobRepository" ref="jobRepository"/>
    </bean>

    <!--定义事务管理器,用于Spring Batch框架中对数据操作提供事务能力-->
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>

    <!--读取信用卡账单文件,CSV 格式-->
    <!--使用FlatFileItemReader读文本文件-->
    <bean id="csvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
        <!--指定读取的资源文件-->
        <property name="resource" value="#{jobParameters['inputResource']}"/>
        <!--通过lineMapper把文本中的一行转换为领域对象creditBill-->
        <property name="lineMapper">
            <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
                <!--lineTokenizer定义文本中每行的分隔符号-->
                <property name="lineTokenizer" ref="lineTokenizer"/>
                <!--fieldSetMapper定义了转换结果映射,即具体映射到哪个Java类对象-->
                <property name="fieldSetMapper">
                    <bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                        <property name="prototypeBeanName" value="creditBill"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!--lineTokenizer-->
    <bean id="lineTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
        <!--按","符号对行进行切割-->
        <property name="delimiter" value=","/>
        <!--属性名称列表,将切割后的行按顺序投入-->
        <property name="names">
            <list>
                <value>accountID</value>
                <value>name</value>
                <value>amount</value>
                <value>date</value>
                <value>address</value>
            </list>
        </property>
    </bean>

    <!--注入实体类-->
    <bean id="creditBill" class="com.xj.demo8.CreditBill" scope="prototype"></bean>

    <!--数据处理类-->
    <bean id="creditBillProcessor" class="com.xj.demo8.CreditBillProcessor" scope="step"></bean>

    <!--写信用卡账单文件,CSV格式-->
    <bean id="csvItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step">
        <!--要写入的文件位置,因为[classpath:]不是一个具体的目录,这里应当用[file:](从项目根目录开始)指明输出位置-->
        <property name="resource" value="#{jobParameters['outputResource']}"/>
        <!--[lineAggregator成员]指明行聚合器,用来将对象输出到文件时构造文件中的每行的格式-->
        <property name="lineAggregator">
            <!--这里使用Spring Batch自带的DelimitedLineAggregator来作为行聚合器(可以拼接一个个属性形成行)-->
            <bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
                <!--使用","拼接-->
                <property name="delimiter" value=","/>
                <!--fieldExtractor成员用来将Java类的属性组成的数组拼接成行字符串-->
                <property name="fieldExtractor">
                    <bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
                        <property name="names" value="accountID,name,amount,date,address">
                        </property>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
</beans>

pom.xml:

    <groupId>com.xj</groupId>
    <artifactId>spring-batch</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <!--使用org.apache.maven.plugins.maven-dependency-plugin打包-->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.5.1</version>
                <!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,默认为false-->
                <executions>
                    <!--execution元素包含了插件执行需要的信息-->
                    <execution>
                        <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标-->
                        <id>copy-dependencies</id>
                        <!--绑定了目标的构建生命周期阶段,即声明goals执行的时期。如果省略,目标会被绑定到源数据里配置的默认阶段-->
                        <phase>package</phase>
                        <!--配置的执行目标-->
                        <goals>
                            <!--要执行的goal,即copy-dependencies,将所有依赖项复制到target/dependency-jars中-->
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!--打包文件输出路径-->
                            <outputDirectory>
                                ${project.build.directory}/dependency-jars/
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

使用Maven将您的项目打包到单个jar文件– target / your-project.jar中 ,然后将所有依赖项复制到target / dependency-jars /中 。

三、项目打包

四、运行结果

根据配置情况输入指令:

java -classpath "target/dependency-jars/*;target/spring-batch-1.0-SNAPSHOT.jar" org.springframework.batch.core.launch.support.CommandLineJobRunner demo8/job/demo8-job.xml billJob

注意:这里是windows系统的话,分隔符用“;”,如果是Linux系统的话,就用“:”。

五、添加额外参数运行方式

        将demo8-job.xml文件中的导入文件变更为配置文件demo8-jobContext2.xml,然后重新使用maven打包,即package一下。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">

    <!--导入文件-->
    <import resource="classpath:demo8/job/demo8-jobContext2.xml"/>

        . . . . . . . . .
</beans>

根据配置情况输入指令:

java -classpath "target/dependency-jars/*;target/spring-batch-1.0-SNAPSHOT.jar" org.springframework.batch.core.launch.support.CommandLineJobRunner demo8/job/demo8-job.xml billJob inputResource(string)=demo8/data/demo8-inputFile2.csv outputResource(string)=file:src/main/resources/demo8/data/demo8-outputFile2.csv date(string)=2021/12/06

注意,其中“String”都改为“string”。

运行代码:

六、注意事项

        使用CommandLineJobRunner进行命令行执行过程中,spring对CommandLineJobRunner中的依赖全部使用基于类型的自动装配。例如CommandLineJobRunner中的属性launcher,Spring会自动基于类型的JobLauncher进行装配,如果没有JobLauncher的定义或者有多个定义都会导致错误。

七、参考文献

1.使用CommandLineJobRunner运行Spring批处理作业_一名可爱的技术搬运工-CSDN博客

2.Run Spring batch job with CommandLineJobRunner(三) - yzhming - 博客园

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值