使用 JDBC 进行读取的 Spring Batch 应用程序无法启动
SpringBatch App Using JDBC for Reading is Failing to Start
我有一些与下面的代码非常相似的东西(我不得不做一些混淆)。我收到应用程序启动失败错误。未显示的代码是数据源 bean 和 spring 引导应用程序 class。当我在调试中放置断点和所有 运行 时,除了 Job 和 Step bean 之外的所有 bean 似乎都被创建了,它们似乎被完全跳过了。我不确定如何进一步诊断。似乎是一些 Spring 魔法问题。非常感谢任何想法。
这里是例外:
2020-08-23 11:26:50.264 INFO 12195 --- [main] o.apache.catalina.core.StandardService:启动服务 [Tomcat]
2020-08-23 11:26:50.265 INFO 12195 --- [main] org.apache.catalina.core.StandardEngine:启动 Servlet 引擎:[Apache Tomcat/9.0.31]
2020-08-23 11:26:50.382 INFO 12195 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]:正在初始化 Spring 嵌入式 WebApplicationContext
2020-08-23 11:26:50.383 INFO 12195 --- [main] o.s.web.context.ContextLoader:Root WebApplicationContext:初始化在 2276 毫秒内完成
2020-08-23 11:26:57.552 WARN 12195 --- [main] ConfigServletWebServerApplicationContext:上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为 'databaseCursorStep' 的 bean 时定义错误class路径资源[/com/configuration/BatchConfig.class]:通过方法'databaseCursorStep'参数0表达的不满足依赖;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有 'org.springframework.batch.item.ItemReader<com.dto.StuffDto>' 类型的合格 bean 可用:预计至少有 1 个 bean 有资格作为自动装配候选者。依赖注解:{@org.springframework.beans.factory.annotation.Qualifier(value=databaseCursorItemReader)}
2020-08-23 11:26:57.572 INFO 12195 --- [main] o.apache.catalina.core.StandardService:停止服务 [Tomcat]
2020-08-23 11:26:57.603 信息 12195 --- [主要] ConditionEvaluationReportLoggingListener:
启动 ApplicationContext 时出错。要显示条件报告,请重新 运行 您的应用程序并启用 'debug'。
2020-08-23 11:26:57.908 错误 12195 --- [主要] o.s.b.d.LoggingFailureAnalysisReporter :
应用程序启动失败
描述:
com.configuration.BatchConfig 中的方法 databaseCursorStep 的参数 0 需要找不到类型 'org.springframework.batch.item.ItemReader' 的 bean。
注入点有以下注解:
- @org.springframework.beans.factory.annotation.Qualifier(值=databaseCursorItemReader)
操作:
考虑在您的配置中定义类型为 'org.springframework.batch.item.ItemReader' 的 bean。
已与目标 VM 断开连接,地址:'127.0.0.1:46088',传输:'socket'
进程已完成,退出代码为 1
代码如下:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
private static final String GET_DATA =
"SELECT " +
"stuffA, " +
"stuffB, " +
"FROM STUFF_TABLE " +
"ORDER BY stuffA ASC";
@Bean
public ItemReader<StuffDto> itemReader(DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<StuffDto>()
.name("cursorItemReader")
.dataSource(dataSource)
.sql(GET_DATA)
.rowMapper(new BeanPropertyRowMapper<>(StuffDto.class))
.build();
}
@Bean
ItemProcessor<StuffDto, StuffDto> databaseXmlItemProcessor() {
return new QueryLoggingProcessor();
}
@Bean
public ItemWriter<StuffDto> databaseCursorItemWriter() {
return new LoggingItemWriter();
}
@Bean
public Step databaseCursorStep(@Qualifier("databaseCursorItemReader") ItemReader<StuffDto> reader,
@Qualifier("databaseCursorItemWriter") ItemWriter<StuffDto> writer,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("databaseCursorStep")
.<StuffDto, StuffDto>chunk(1)
.reader(reader)
.writer(writer)
.build();
}
@Bean
public Job databaseCursorJob(@Qualifier("databaseCursorStep") Step exampleJobStep,
JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory.get("databaseCursorJob")
.incrementer(new RunIdIncrementer())
.flow(exampleJobStep)
.end()
.build();
}
}
您的 Qualifier Bean 名称是 itemReader
而不是 databaseCursorItemReader
。更改方法名称或更改为 databaseCursorStep(@Qualifier("itemReader")
@Bean
public Step databaseCursorStep(@Qualifier("itemReader") ItemReader<StuffDto> reader,
@Qualifier("databaseCursorItemWriter") ItemWriter<StuffDto> writer,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("databaseCursorStep")
.<StuffDto, StuffDto>chunk(1)
.reader(reader)
.writer(writer)
.build();
}
@Bean
public ItemReader<StuffDto> itemReader(DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<StuffDto>()
.name("cursorItemReader")
.dataSource(dataSource)
.sql(GET_DATA)
.rowMapper(new BeanPropertyRowMapper<>(StuffDto.class))
.build();
}
我有一些与下面的代码非常相似的东西(我不得不做一些混淆)。我收到应用程序启动失败错误。未显示的代码是数据源 bean 和 spring 引导应用程序 class。当我在调试中放置断点和所有 运行 时,除了 Job 和 Step bean 之外的所有 bean 似乎都被创建了,它们似乎被完全跳过了。我不确定如何进一步诊断。似乎是一些 Spring 魔法问题。非常感谢任何想法。
这里是例外:
2020-08-23 11:26:50.264 INFO 12195 --- [main] o.apache.catalina.core.StandardService:启动服务 [Tomcat] 2020-08-23 11:26:50.265 INFO 12195 --- [main] org.apache.catalina.core.StandardEngine:启动 Servlet 引擎:[Apache Tomcat/9.0.31] 2020-08-23 11:26:50.382 INFO 12195 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]:正在初始化 Spring 嵌入式 WebApplicationContext 2020-08-23 11:26:50.383 INFO 12195 --- [main] o.s.web.context.ContextLoader:Root WebApplicationContext:初始化在 2276 毫秒内完成 2020-08-23 11:26:57.552 WARN 12195 --- [main] ConfigServletWebServerApplicationContext:上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为 'databaseCursorStep' 的 bean 时定义错误class路径资源[/com/configuration/BatchConfig.class]:通过方法'databaseCursorStep'参数0表达的不满足依赖;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有 'org.springframework.batch.item.ItemReader<com.dto.StuffDto>' 类型的合格 bean 可用:预计至少有 1 个 bean 有资格作为自动装配候选者。依赖注解:{@org.springframework.beans.factory.annotation.Qualifier(value=databaseCursorItemReader)} 2020-08-23 11:26:57.572 INFO 12195 --- [main] o.apache.catalina.core.StandardService:停止服务 [Tomcat] 2020-08-23 11:26:57.603 信息 12195 --- [主要] ConditionEvaluationReportLoggingListener:
启动 ApplicationContext 时出错。要显示条件报告,请重新 运行 您的应用程序并启用 'debug'。 2020-08-23 11:26:57.908 错误 12195 --- [主要] o.s.b.d.LoggingFailureAnalysisReporter :
应用程序启动失败
描述:
com.configuration.BatchConfig 中的方法 databaseCursorStep 的参数 0 需要找不到类型 'org.springframework.batch.item.ItemReader' 的 bean。
注入点有以下注解: - @org.springframework.beans.factory.annotation.Qualifier(值=databaseCursorItemReader)
操作:
考虑在您的配置中定义类型为 'org.springframework.batch.item.ItemReader' 的 bean。
已与目标 VM 断开连接,地址:'127.0.0.1:46088',传输:'socket'
进程已完成,退出代码为 1
代码如下:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
private static final String GET_DATA =
"SELECT " +
"stuffA, " +
"stuffB, " +
"FROM STUFF_TABLE " +
"ORDER BY stuffA ASC";
@Bean
public ItemReader<StuffDto> itemReader(DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<StuffDto>()
.name("cursorItemReader")
.dataSource(dataSource)
.sql(GET_DATA)
.rowMapper(new BeanPropertyRowMapper<>(StuffDto.class))
.build();
}
@Bean
ItemProcessor<StuffDto, StuffDto> databaseXmlItemProcessor() {
return new QueryLoggingProcessor();
}
@Bean
public ItemWriter<StuffDto> databaseCursorItemWriter() {
return new LoggingItemWriter();
}
@Bean
public Step databaseCursorStep(@Qualifier("databaseCursorItemReader") ItemReader<StuffDto> reader,
@Qualifier("databaseCursorItemWriter") ItemWriter<StuffDto> writer,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("databaseCursorStep")
.<StuffDto, StuffDto>chunk(1)
.reader(reader)
.writer(writer)
.build();
}
@Bean
public Job databaseCursorJob(@Qualifier("databaseCursorStep") Step exampleJobStep,
JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory.get("databaseCursorJob")
.incrementer(new RunIdIncrementer())
.flow(exampleJobStep)
.end()
.build();
}
}
您的 Qualifier Bean 名称是 itemReader
而不是 databaseCursorItemReader
。更改方法名称或更改为 databaseCursorStep(@Qualifier("itemReader")
@Bean
public Step databaseCursorStep(@Qualifier("itemReader") ItemReader<StuffDto> reader,
@Qualifier("databaseCursorItemWriter") ItemWriter<StuffDto> writer,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("databaseCursorStep")
.<StuffDto, StuffDto>chunk(1)
.reader(reader)
.writer(writer)
.build();
}
@Bean
public ItemReader<StuffDto> itemReader(DataSource dataSource) {
return new JdbcCursorItemReaderBuilder<StuffDto>()
.name("cursorItemReader")
.dataSource(dataSource)
.sql(GET_DATA)
.rowMapper(new BeanPropertyRowMapper<>(StuffDto.class))
.build();
}