SpringBatch异常To use the default BatchConfigurer the context must contain no more thanone DataSource
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!
如果有其他更好的方法,还请不吝赐教。
最新文章
- Django+Tastypie作后端,RequireJS+Backbone作前端的TodoMVC
- web测试安全性常见问题
- USACO2007Monthly Expense月度开销
- 再也不用管UIImagePicker的代理了
- 关于python中PIL的安装
- Java实现批量修改文件名称
- 数据库添加数据I
- Android图形合成和显示系统---基于高通MSM8k MDP4平台
- bootstarp栅格系统
- 利用Crowbar抓取网页异步加载的内容 [Python俱乐部]
- eKing Cloud基础云平台演进之路
- 阿里巴巴开源 Spring Cloud Alibaba,加码微服务生态建设
- Fiddler 只取所需
- 深入理解Java虚拟机2-chap3-斗之气9段
- SharePoint 设置客户端上传文件大小
- [Python]利用type()动态创建类
- 检测浏览器对HTML5新input类型的支持
- ios开发--图文混排(富文本)
- HDU 5318——The Goddess Of The Moon——————【矩阵快速幂】
- PL/SQL 查询结果集直接修改数据