gpt4 book ai didi

java - 具有两个不同数据源问题的 Spring Batch

转载 作者:搜寻专家 更新时间:2023-11-01 01:51:16 25 4
gpt4 key购买 nike

我有一个简单的 Spring Batch 应用程序,它从数据库中提取记录并将行打印到屏幕上。只是一个简单的 POC 应用程序。

该应用程序在 Spring Boot 1.2.1.RELEASE 上工作得很好,但是当我更新到 1.2.3.RELEASE 时,我收到一条关于“没有定义 [javax.sql.DataSource] 类型的合格 bean”的错误消息

我不确定这是 Spring Boot 问题还是 Spring Batch 问题。

有没有办法为 Spring Batch 存储库显式定义数据源?

完整的堆栈跟踪。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [demo/BatchConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,consumerAppointmentDataSource
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at demo.Application.main(Application.java:13)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.Collection org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.dataSources; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [demo/BatchConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,consumerAppointmentDataSource
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 15 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [demo/BatchConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,consumerAppointmentDataSource
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:996)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 17 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceInitializer': Invocation of init method failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,consumerAppointmentDataSource
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:217)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:350)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.postProcessAfterInitialization(DataSourceInitializerPostProcessor.java:62)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 26 common frames omitted
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource,consumerAppointmentDataSource
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:365)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.init(DataSourceInitializer.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
... 40 common frames omitted

示例代码

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

@Bean
@ConfigurationProperties(prefix = "datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix = "datasource.consumerappointment")
public DataSource consumerAppointmentDataSource() {
return DataSourceBuilder.create().build();
}



@Bean
public Job importUserJob(JobBuilderFactory jobs, Step s1) {
return jobs.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(s1)
.end()
.build();
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<AppointmentVerification> reader,
ItemProcessor<AppointmentVerification, AppointmentVerification> processor) {
return stepBuilderFactory.get("step1")
.<AppointmentVerification, AppointmentVerification> chunk(10)
.reader(reader)
.processor(processor)
.build();
}

@Bean
public ItemProcessor<AppointmentVerification, AppointmentVerification> processorAppointmentVerification() {
return new AppointmentVerificationItemProcessor();
}

@Bean
public ItemReader<AppointmentVerification> appointmentVerificationReader(DataSource consumerAppointmentDataSource) {
JdbcCursorItemReader<AppointmentVerification> reader = new JdbcCursorItemReader<AppointmentVerification>();
String sql = "select * from test";
reader.setSql(sql);
reader.setDataSource(consumerAppointmentDataSource);
reader.setRowMapper(rowMapper());
return reader;
}

private RowMapper<AppointmentVerification> rowMapper() {

return new RowMapper<AppointmentVerification>() {

@Override
public AppointmentVerification mapRow(ResultSet rs, int i)
throws SQLException {
AppointmentVerification appointmentVerification = new AppointmentVerification();
appointmentVerification.setEmail(rs.getString("CNSM_EML_ADR"));
return appointmentVerification;
}
};
}

}

编辑修复:将主数据源更新为主要数据源创建了一个 BatchConfigurer bean。向 itemreader 添加一个@Qualifier

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

@Primary
@Bean
@ConfigurationProperties(prefix = "datasource.batch")
public DataSource batchDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix = "datasource.consumerappointment")
public DataSource consumerAppointmentDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
public BatchConfigurer configurer(DataSource batchDataSource){
return new DefaultBatchConfigurer(batchDataSource);
}

@Bean
public Job importUserJob(JobBuilderFactory jobs, Step s1) {
return jobs.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(s1)
.end()
.build();
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<AppointmentVerification> reader,
ItemWriter<AppointmentVerification> messageWriter) {
return stepBuilderFactory.get("step1")
.<AppointmentVerification, AppointmentVerification> chunk(10)
.reader(reader)
.writer(messageWriter)
.build();
}

@Bean
public ItemReader<AppointmentVerification> appointmentVerificationReader(@Qualifier(value = "consumerAppointmentDataSource") DataSource consumerAppointmentDataSource) {
JdbcCursorItemReader<AppointmentVerification> reader = new JdbcCursorItemReader<AppointmentVerification>();
String sql = "select * from test";
reader.setSql(sql);
reader.setDataSource(consumerAppointmentDataSource);
reader.setRowMapper(rowMapper());
return reader;
}

private RowMapper<AppointmentVerification> rowMapper() {

return new RowMapper<AppointmentVerification>() {
@Override
public AppointmentVerification mapRow(ResultSet rs, int i) throws SQLException {
AppointmentVerification appointmentVerification = new AppointmentVerification();
appointmentVerification.setEmail(rs.getString("CNSM_EML_ADR"));
return appointmentVerification;
}
};
}

最佳答案

将您的一个 bean 标记为主要 bean

@Primary
@Bean
@ConfigurationProperties(prefix = "datasource.consumerappointment")
public DataSource consumerAppointmentDataSource() {
return DataSourceBuilder.create().build();
}

然后用它创建一个 BatchConfigurer

@Bean
BatchConfigurer configurer(DataSource dataSource){
return new DefaultBatchConfigurer(dataSource);
}

关于java - 具有两个不同数据源问题的 Spring Batch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30537375/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com