Spring Batch –用JavaConfig替换XML作业配置

最近,我协助一个客户启动并运行了Spring Batch实现。 该团队决定继续使用针对批处理作业的基于JavaConfig的配置,而不是传统的基于XML的配置。 随着这越来越成为配置Java应用程序的一种常用方法,我觉得是时候更新Keyhole的Spring Batch系列了 ,向您展示如何将现有的基于XML的Spring Batch配置转换为基于JavaConfig批注的新配置。

Spring批 本教程将使用在我们的第二批Spring教程( https://keyholesoftware.com/2012/06/25/getting-started-with-spring-batch-part-two/ )中找到的简单批处理作业。

房子清洁

在开始转换过程之前,我们需要对项目进行一些房屋清洁。

  1. 尚未将Java构建和Spring环境升级到Java 7。
  2. 将Spring Boot依赖项添加到Maven pom.xml:
  3. <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId><version>1.2.4.RELEASE</version>
    </dependency>
  4. 将Spring Batch版本修改为3.0.4.RELEASE,并将Spring Framework版本修改为4.1.6.RELEASE
    <properties>                              <spring.framework.version>4.1.6.RELEASE</spring.framework.version><spring.batch.version>3.0.4.RELEASE</spring.batch.version>
    </properties>
  5. 在名为module-context.xml的原始批处理配置文件中注释掉作业定义。
  6. 在名为launch-context.xml的配置文件中注释掉Spring应用程序上下文配置元素。
  7. 注释掉Reader,Processor和Writer元素上的@Component批注。 不要注释掉CurrencyConversionServiceImpl类上的@Service批注。

构建基于JavaConfig的配置

现在我们已经删除或禁用了现有的基于XML的配置,我们可以开始构建基于JavaConfig的配置。 为此,我们需要创建一个带有一些注释的新类,这些注释为配置奠定了基础。

package com.keyhole.example.config;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.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableBatchProcessing
public class TickerPriceConversionConfig {@Autowiredprivate JobBuilderFactory jobs;@Autowiredprivate StepBuilderFactory steps;}

@Configuration注释使Spring容器知道该类将包含一个或多个@Bean注释的方法,这些方法将在运行时进行处理以生成Bean定义和服务请求。

@EnableBatchProcessing批注提供了用于构建批处理作业配置的基本配置。 Spring Batch使用此注释来设置默认的JobRepository,JobLauncher,JobRegistry,PlatformTransactionManager,JobBuilderFactory和StepBuilderFactory。

现在是时候为组成批处理作业的组件添加@Bean注释的方法了。 作为参考,我为每个bean提供了相应的XML配置。

ItemReader配置

<bean name="tickerReader"class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource"
value="http://finance.yahoo.com/d/quotes.csv?s=XOM+IBM+JNJ+MSFT&f=snd1ol1p2" /><property name="lineMapper" ref="tickerLineMapper" />
</bean><bean name="tickerLineMapper"
class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="fieldSetMapper" ref="tickerMapper" /><property name="lineTokenizer" ref="tickerLineTokenizer" />
</bean><bean name="tickerLineTokenizer"
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" />
@Beanpublic ItemReader<TickerData> reader() throws MalformedURLException {FlatFileItemReader<TickerData> reader = new FlatFileItemReader<TickerData>();reader.setResource(new UrlResource("http://finance.yahoo.com/d/quotes.csv?s=XOM+IBM+JNJ+MSFT&f=snd1ol1p2"));reader.setLineMapper(new DefaultLineMapper<TickerData>() {{setLineTokenizer(new DelimitedLineTokenizer());setFieldSetMapper(new TickerFieldSetMapper());}});return reader;}

ItemProcessor和ItemWriter以前使用Spring容器的@Component注释来拾取bean并将其加载到应用程序上下文中。

@Beanpublic ItemProcessor<TickerData, TickerData> processor() {return new TickerPriceProcessor();}@Beanpublic ItemWriter<TickerData> writer() {return new LogItemWriter();}

现在我们已经定义了Spring bean,我们可以创建@Bean注释的方法来表示步骤和工作。 作为参考,我包括了相应的XML配置。

<batch:job id="TickerPriceConversion"><batch:step id="convertPrice"><batch:tasklet transaction-manager="transactionManager"><batch:chunk reader="tickerReader"processor="tickerPriceProcessor"writer="tickerWriter" commit-interval="10" /></batch:tasklet></batch:step></batch:job>
@Beanpublic Job TickerPriceConversion() throws MalformedURLException {return jobs.get("TickerPriceConversion").start(convertPrice()).build();}@Beanpublic Step convertPrice() throws MalformedURLException {return steps.get("convertPrice").<TickerData, TickerData> chunk(5).reader(reader()).processor(processor()).writer(writer()).build();}

我将在文章的末尾包含TickerPriceConversionConfig类的完整代码,以供参考,但基本上这就是全部!

一旦定义了Spring bean并使用JobBuilderFactory和StepBuilderFactory为批处理作业和步骤创建Bean配置,就可以运行该作业并测试配置了。 为了运行作业,我们将使用Spring Boot来测试新转换的作业配置的执行情况。 为此,我们将在测试包中创建一个名为TickerPriceConversionJobRunner的新类。

源代码如下所示:

package com.keyhole.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class TickerPriceConversionJobRunner {public static void main(String[] args) {SpringApplication.run(TickerPriceConversionJobRunner.class, args);}}

@SpringBootApplication注释本质上是一个便捷注释,它提供了通常使用@ Configuration,@ EnableAutoConfiguration和@ComponentScan可以获得的功能。 TickerPriceConversionJobRunner是一个简单的Java应用程序,它将主要方法处理委托给Spring Boot的SpringApplication类来运行该应用程序。

现在,您可以将该项目导出为jar并从命令行运行TickerPriceConversionJobRunner,或者,如果您想在Spring STS中运行它,则可以右键单击该类,然后选择Run As→Spring Boot Application。

最终想法和代码清单

如您所见,创建Spring Batch作业配置并不需要很多工作,但是如果您决定将所有现有作业从基于XML的配置转换为较新的基于JavaConfig的配置,摆在您前面的工作。 大部分工作将花费大量时间来充分回归测试转换后的批处理作业。

如果您拥有大量的Spring Batch作业库,那将值得吗? 可能不是,但是如果您刚开始使用或具有可管理的批处理库,那么这绝对是我会采用的方法。

TickerPriceConversionConfig的代码清单

package com.keyhole.example.config;import java.net.MalformedURLException;import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
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.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.UrlResource;import com.keyhole.example.LogItemWriter;
import com.keyhole.example.TickerData;
import com.keyhole.example.TickerFieldSetMapper;
import com.keyhole.example.TickerPriceProcessor;@Configuration
@EnableBatchProcessing
public class TickerPriceConversionConfig {@Autowiredprivate JobBuilderFactory jobs;@Autowiredprivate StepBuilderFactory steps;@Beanpublic ItemReader<TickerData> reader() throws MalformedURLException {FlatFileItemReader<TickerData> reader = new FlatFileItemReader<TickerData>();reader.setResource(new UrlResource("http://finance.yahoo.com/d/quotes.csv?s=XOM+IBM+JNJ+MSFT&f=snd1ol1p2"));reader.setLineMapper(new DefaultLineMapper<TickerData>() {{setLineTokenizer(new DelimitedLineTokenizer());setFieldSetMapper(new TickerFieldSetMapper());}});return reader;}@Beanpublic ItemProcessor<TickerData, TickerData> processor() {return new TickerPriceProcessor();}@Beanpublic ItemWriter<TickerData> writer() {return new LogItemWriter();}@Beanpublic Job TickerPriceConversion() throws MalformedURLException {return jobs.get("TickerPriceConversion").start(convertPrice()).build();}@Beanpublic Step convertPrice() throws MalformedURLException {return steps.get("convertPrice").<TickerData, TickerData> chunk(5).reader(reader()).processor(processor()).writer(writer()).build();}
}

TickerPriceConversionJobRunner的代码清单

  • 代码项目
package com.keyhole.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class TickerPriceConversionJobRunner {public static void main(String[] args) {SpringApplication.run(TickerPriceConversionJobRunner.class, args);}}

翻译自: https://www.javacodegeeks.com/2015/07/spring-batch-replacing-xml-job-configuration-with-javaconfig.html

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

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

相关文章

python 共轭转置_python矩阵运算,转置,逆运算,共轭矩阵实例

我就废话不多说了&#xff0c;大家还是直接看代码吧&#xff01;#先定义两个矩阵Xnp.array([[1,2104,5,1,45],[1,1416,3,2,40],[1,1534,3,2,30],[1,852,2,1,36]])ynp.array([45,40,30,36])#内积以后发现cnp.dot(X.T,X)carray([[ 4, 5906, 13, 6, 151],[ 5906, 9510932, 21074, …

python解析pcap包已text格式输出_python分析pcap包

前两天需要分析一个pcap包&#xff0c;写了一段python脚本&#xff0c;将每个包的基本信息(源/目的MAC、源/目的IP、源/目的端口)提取出来。在实现过程中为了省事用了dpkt开发包&#xff0c;不过只用了几个简单的函数&#xff0c;具体的信息提取部分都是自己实现的。值得注意的…

sql limit 子句_Java 8流中的常见SQL子句及其等效项

sql limit 子句功能编程允许使用通用语言进行准声明性编程 。 通过使用功能强大的流畅API&#xff08;例如Java 8的Stream API &#xff09;或jOOλ的顺序Stream扩展Seq或更复杂的库&#xff08;例如javaslang或functionaljava&#xff09; &#xff0c;我们可以以一种非常简洁…

C++编程中的核心知识点!

点击蓝字关注我们来源于网络&#xff0c;侵删尊重函数接口&#xff0c;尽量不作内部改动C代码语句分为&#xff1a;内置类型&#xff0c;名字&#xff0c;变量&#xff0c;操作符&#xff0c;标量&#xff0c;字符串&#xff0c;预处理指示&#xff08;如#include&#xff09;等…

python3.70_Python3 基本数据类型

Python3 基本数据类型Python 中的变量不需要声明。每个变量在使用前都必须赋值&#xff0c;变量赋值以后该变量才会被创建。在 Python 中&#xff0c;变量就是变量&#xff0c;它没有类型&#xff0c;我们所说的"类型"是变量所指的内存中对象的类型。等号()用来给变量…

jdbc mysql驱动_MySQL JDBC驱动程序如何处理准备好的语句

jdbc mysql驱动准备的语句类型 在研究《 高性能Java持久性》一书中的“ 语句缓存”一章时&#xff0c;我有机会比较了Oracle&#xff0c;SQL Server&#xff0c;PostgreSQL和MySQL处理预准备语句的方式。 感谢Jess Balint &#xff08;MySQL JDBC驱动程序撰稿人&#xff09;在…

C++ 语言的单元测试与代码覆盖率

点击蓝字关注我们来源于网络&#xff0c;侵删前言测试是软件开发过程中一个必须的环节&#xff0c;测试确保软件的质量符合预期。对于工程师自己来说&#xff0c;单元测试也是提升自信心的一种方式。直接交付没有经过测试的代码是不太好的&#xff0c;因为这很可能会浪费整个团…

使用Spring AOP和番石榴速率限制器的节气门方法

外部服务或API可能有使用限制&#xff0c;或者它们不能失败就无法处理大量请求。 这篇文章解释了如何创建一个基于Spring Framework的方面&#xff0c;该方面可以用来限制使用Guava速率限制器的任何建议方法调用。 以下实现需要Java 8&#xff0c;Spring AOP和Guava。 让我们从…

C++ 模板(Template)总结,长点小知识

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删前言&#xff1a;大家好&#xff0c;今天给大家分享一篇关于 C 模板总结概述.模板&#xff08;Template&#xff09;指 C 程序设计设计语言中采用…

归并排序 java_归并排序(Java实现)

package primary_01;/** 归并排序* 1.算法实现* 2.验证算法的正确性* 3.分析算法的复杂度*/public class Merge_sort {public static void main(String[] args) {int arr [] {2,1,6,5,9,8,2020,199};sort(arr, 0, arr.length-1);for (int i : arr) {System.out.print(i" &…

python kotlin_在Python,Java和Kotlin中标记参数和重载

python kotlin在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异。 比较有趣的差异之一与一个函数执行多项操作有关。 Python 我们先来看一下Python。 Python实际上无法重载&#xff0c;因为用相同的名称定义一个新的函数/方法只会覆盖前一个…

python调用zabbixapi接口_python调用zabbix api获取主机信息

import requestsimport jsonheaders {Content-Type: application/json}class GetZabbix:def __init__(self):#用户信息self.username "****"self.password "****"self.url "http://192.168.0.*/zabbix/api_jsonrpc.php"self.token self.get…

C++17 常用新特性:带初始化的 if 和 switch 语句

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删早在2016-03-14&#xff0c;Thomas Kppe 在https://wg21.link/p0305r0中就提出了在if和switch使用初始化语句&#xff0c;使用时的代码示例如下&…

python回归预测例子_案例实战 | 逻辑回归实现客户流失预测(附Python代码与源数据)...

关注一下~&#xff0c;更多商业数据分析案例等你来撩前言利用逻辑回归进行客户流失预警建模中涵盖了许多比较细的知识点&#xff0c;思维导图只展示了极小的一部分&#xff0c;相关知识点链接将穿插在文中。(源数据源代码空降文末获取)数据读入数据属性说明数据探索简洁版本&am…

latex中算法命令_比较Java 8中的命令式和功能性算法

latex中算法命令Mario Fusco受欢迎的推文令人印象深刻&#xff0c;显示了类似算法的命令性和功能性方法之间的主要区别实际上是&#xff1a; 势在必行–功能分离pic.twitter.com/G2cC6iBkDJ — Mario Fusco&#xff08;mariofusco&#xff09; 2015年3月1日 两种算法都做同样…

四大语言加强统治地位,Rust威胁C/C++

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删TIOBE 公布了 2022 年 10 月的编程语言排行榜。截至今日&#xff0c;Python、Java、C 和 C 语言已经在 TIOBE 榜单的前 4 位盘踞了相当长的一段时…

sql计算留存_SQL无所不能:DBA宝妈宝爸系列分享

原文链接&#xff1a;https://www.modb.pro/db/22315 目前程序从功能上其实已经完全满足客户(当然我这里的客户都是指媳妇儿)需求&#xff0c;具体可参考&#xff1a;使用SQL计算宝宝每次吃奶的时间间隔 - Part1&#xff1a;分析函数的使用使用SQL计算宝宝每次吃奶的时间间隔 -…

java8流分组 性能_Java性能教程– Java 8流有多快?

java8流分组 性能在此JAX Magazine的预览预览中&#xff0c;JAX伦敦发言人Angelika Langer为使用Java流的任何人回答了最重要的问题&#xff1a;它们真的更快吗&#xff1f; Java 8是JDK收集框架的主要补充&#xff0c;即流​​API。 与集合相似&#xff0c;流表示元素序列。 …

对 int 变量赋值的操作是原子的吗?为什么?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删这个是在面试的时候遇到的问题&#xff0c;当时没有答出来。回到家以后查了查&#xff0c;整理记录下来。原问题&#xff1a;什么指令集支持原子…

C语言知识总结:if-else判断语句和switch-case选择语句

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删1、if-else判断语句一个基本的if语句由一个关键字if开头&#xff0c;跟上在括号&#xff08;&#xff09;里边的是表示逻辑条件的表达式&#xf…