SpringBoot整合SpringBatch项目,已将代码开源至github,访问地址:https://github.com/cmlbeliever/SpringBatch 欢迎star or fork!

在框架整合的过程中,由于需要添加db读写分离配置,因此项目中有两个DataSource,运行batch后报错如下:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at com.cml.learning.framework.module.BaseModule.run(BaseModule.java:39)
at com.cml.learning.module.bat00X.Bat00XModule.main(Bat00XModule.java:20)
Caused by: java.lang.IllegalStateException: To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2
at org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.getConfigurer(AbstractBatchConfiguration.java:108)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.initialize(SimpleBatchConfiguration.java:114)
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$ReferenceTargetSource.createObject(SimpleBatchConfiguration.java:142)
at org.springframework.aop.target.AbstractLazyCreationTargetSource.getTarget(AbstractLazyCreationTargetSource.java:86)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192)
at com.sun.proxy.$Proxy55.getJobInstances(Unknown Source)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.getNextJobParameters(JobLauncherCommandLineRunner.java:131)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:212)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:231)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:123)
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:117)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776)
... 5 common frames omitted

意思是要使用default BatchConfigurer,则项目中只能有一个Datasource。

根据异常堆栈信息,找到抛出此异常的源码位置和实现代码:

org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration

@Autowired(required = false)
private Collection<DataSource> dataSources; protected BatchConfigurer getConfigurer(Collection<BatchConfigurer> configurers) throws Exception {
if (this.configurer != null) {
return this.configurer;
}
if (configurers == null || configurers.isEmpty()) {
if (dataSources == null || dataSources.isEmpty()) {
DefaultBatchConfigurer configurer = new DefaultBatchConfigurer();
configurer.initialize();
this.configurer = configurer;
return configurer;
} else if(dataSources != null && dataSources.size() == 1) {
DataSource dataSource = dataSources.iterator().next();
DefaultBatchConfigurer configurer = new DefaultBatchConfigurer(dataSource);
configurer.initialize();
this.configurer = configurer;
return configurer;
} else {
throw new IllegalStateException("To use the default BatchConfigurer the context must contain no more than" +
"one DataSource, found " + dataSources.size());
}
}
if (configurers.size() > 1) {
throw new IllegalStateException(
"To use a custom BatchConfigurer the context must contain precisely one, found "
+ configurers.size());
}
this.configurer = configurers.iterator().next();
return this.configurer;
}

根据源码得知,当数据源不存的时候,BatchConfigure会将batch数据存储到内存中,当数据源只有一个时,会根据数据源建立batch执行所需要的表。当数据源有多个的时候就抛出异常,这样难怪,因为BatchConfigure在多个数据源的时候,它根本不知道要根据哪个数据源建立batch执行所需要的表。

既然知道了原因,只需要自定义BatchConfigure,并且在多数据源的情况下指定一个默认的数据源即可解决。

实现步骤:

1、将框架SimpleBatchConfiguration,AbstractBatchConfiguration源码复制出来

2、重写AbstractBatchConfiguration.getConfigurer方法,设置默认数据源

protected BatchConfigurer getConfigurer(Collection<BatchConfigurer> configurers) throws Exception {
if (this.configurer != null) {
return this.configurer;
}
if (configurers == null || configurers.isEmpty()) {
if (defaultDataSource == null) {
throw new IllegalStateException("Data source can not be null!!!");
} DefaultBatchConfigurer configurer = new DefaultBatchConfigurer(defaultDataSource);
configurer.initialize();
this.configurer = configurer;
return configurer;
}
if (configurers.size() > 1) {
throw new IllegalStateException("To use a custom BatchConfigurer the context must contain precisely one, found " + configurers.size());
}
this.configurer = configurers.iterator().next();
return this.configurer;
}

3、添加注解,将重写的BatchConfigure引入

@Import({ SimpleBatchConfiguration.class })

4、经过以上三个步骤,即可实现多数据源下SpringBatch启动报错问题

以上代码已经整合到SpringBatch,已将代码开源至github,访问地址:https://github.com/cmlbeliever/SpringBatch 欢迎star or fork!

如果有其他更好的方法,还请不吝赐教。

SpringBatch异常To use the default BatchConfigurer the context must contain no more thanone DataSource的更多相关文章

  1. Hibernate 异常 —— Unable to instantiate default tuplize

    出现这个异常 —— Unable to instantiate default tuplizer ,是 Hibernate 的映射文件(*.hbm.xml)导致的.仔细检查一下工程里的映射文件吧. 笔 ...

  2. spring异常 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderServlet

    spring异常 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderServlet   情况 ...

  3. asp.net4.0在Global中的Application_Start 中直接或间接使用 HttpUtility.UrlEncode等出现异常Response is not available in this context的解决方法

    HttpUtility.HtmlEncode HttpUtility.HtmlDecode HttpUtility.UrlEncode HttpUtility.UrlDecode 也会出现此异常. 这 ...

  4. ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed

    1.  问题描述 最近使用ABP .Net Core框架做一个微信开发,同时采用了一个微信开发框架集成到ABP,在微信用户关注的推送事件里调用了一个async 方法,由于没有返回值,也没做任何处理,本 ...

  5. Linux Kernel Oops异常分析

    1.PowerPC小系统内核异常分析 1.1  异常打印 Unable to handle kernel paging request for data at address 0x36fef31eFa ...

  6. .NET异常问题总结

    输入字符串的格式不正确. 有格式化字符替换符号{0}等,“{”和“}”作为特殊符号出现,如果有多余的“{”和“}”就会出错 GZIP压缩出现FF-F0-F1…是无效的输入流 要解压的字节流无效,可能是 ...

  7. Android程序Crash时的异常上报

    转载请注明来源:http://blog.csdn.net/singwhatiwanna/article/details/17289479 前言 大家都知道,android应用不可避免的会发生crash ...

  8. response.sendRedirect 报 java.lang.IllegalStateException 异常的解决思路

    今天在进行代码开发的时候,出现了 java.lang.IllegalStateException异常,response.sendRedirect("./DEFAULT.html") ...

  9. HIbernate常见异常(转载)

    SSH阶段常见的异常系列之一hibernate(15条) 异常一 异常一 异常描述: Sax解析异常:cvc-复杂的类型,发现了以元素maping开头的无效内容,应该是以 ‘{“http://www. ...

随机推荐

  1. C# 基础知识系列- 12 任务和多线程

    0. 前言 照例一份前言,在介绍任务和多线程之前,先介绍一下异步和同步的概念.我们之间介绍的知识点都是在同步执行,所谓的同步就是一行代码一行代码的执行,就像是我们日常乘坐地铁通过安检通道一样,想象我们 ...

  2. Springboot:员工管理之添加员工(十(7))

    构建员工添加请求 com\springboot\controller\EmployeeController.java /*调转到员工添加页 携带部门信息 restful风格*/ @GetMapping ...

  3. Java IO 流 -- 随机读取和写入流 RandomAccessFile (文件分割和合并)

    RandomAccessFile 相对其它流多了一个seek() 方法指定指针的偏移量. 1.指定起始位置读取剩余内容 public static void test01() throws IOExc ...

  4. scrollview 和 listview滑动冲突解决

    http://blog.csdn.net/wanghao200906/article/details/51084975 http://www.cnblogs.com/shitianzeng/artic ...

  5. 解决Oracle在命令行下无法使用del等键问题

    前言: Oracle使用Linux命令行进行编辑? 有PL/SQL development,SQL development等工具,为何用Linux命令行? 但也免不了有用的的时候 以下是解决在Linu ...

  6. JVM原理以及深度调优(二)

    JVM内存分配 内存分配其实真正来讲是有三种的.但对于JVM来说只有两种 栈内存分配: 大家在调优的过程中会发现有个参数是-Xss 默认是1m,这个内存是栈内存分配, 在工作中会发现栈OutOfMem ...

  7. Springboot以Tomcat为容器实现http重定向到https的两种方式

    1 简介 本文将介绍在Springboot中如何通过代码实现Http到Https的重定向,本文仅讲解Tomcat作为容器的情况,其它容器将在以后一一道来. 建议阅读之前的相关文章: (1) Sprin ...

  8. Android 5.0系统默认颜色

    伴随着 Android5.0 的发布也更新了support-v7-appcompat 到 V21,其中增加了 ToolBar.recyclerview.cardview 等控件. Android5.0 ...

  9. 怎么在Chrome和Firefox浏览器中清除HSTS设置?

    HSTS代表的是HTTPS严格传输安全协议,它是一个网络安全政策机制,能够强迫浏览器只通过安全的HTTPS连接(永远不能通过HTTP)与网站交互.这能够帮助防止协议降级攻击和cookie劫持. HST ...

  10. 《Cisco防火墙》一2.4 总结

    本节书摘来自异步社区<Cisco防火墙>一书中的第2章,第2.4节,作者 [巴西]Alexandre M.S.P. Moraes,更多章节内容可以访问云栖社区"异步社区" ...