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. 头文件<cmath>中常用函数

    <cmath>里面有很多数学函数,下面说一下常用的一些函数吧:直接把函数原型给了出来,用的时候注意参数 先说一下,c++自身是没有四舍五入函数round()的,若果你要用到的话,可以自己写 ...

  2. 宝塔利用git+ webhooks 实现git更新远程同步Linux服务器

    参考: https://blog.csdn.net/alipea/article/details/83858177 https://www.bt.cn/bbs/thread-5348-1-1.html ...

  3. JavaScript--'data-'的用法(1)

    HTML5为我们提供了一个强大的功能,前段也也能实现后台数据库的效果,例如data-xxx <a href="#myModal" data-industry_id=" ...

  4. python学习21之高级特性

    '''''''''1.切片(1)谁可以进行切片操作?——列表,元组,字符串(2)切片有以下几种操作'''#[a:b]:取从下标为a的元素开始,到下标为b-1的元素结束L=['aa','bb','cc' ...

  5. Windows VHD Create, Attach, 获得Disk序号

    // create_vhd.cpp : Defines the entry point for the console application. // #include "stdafx.h& ...

  6. Python logging 模块打印异常 exception

    logger.exception(sys.exc_info())

  7. eclipse自动补全导致变量会跟上String后缀的问题解决

    https://blog.csdn.net/feinifi/article/details/103665860

  8. Eureka重点原理解析

    前言 带着问题学习,事半功倍.本文将对如下几个问题进行总结说明: 1.EurekaServer端服务注册的流程和设计模式 2.Eureka服务续约的bug 3.EurekaClient的启动流程 4. ...

  9. mac OS 安装淘宝npm镜像

    淘宝npm镜像官网 https://npm.taobao.org/ 在终端输入 npm install -g cnpm --registry=https://registry.npm.taobao.o ...

  10. Random Number Generator

    rand()函数可以产生[0,RAND_MAX]之间的均匀的伪随机数,它定义在头文件stdlib.h中,函数原型: int rand(void); C标准库的实现是: unsigned ; /*ran ...