使用StepListenerSupport实现Job超时终止时listener方法歧义报错如何解决
错误原因
The method listener(Object) is ambiguous for the type SimpleStepBuilder<UserInfo,UserInfo> 报错的核心原因是SimpleStepBuilder提供了多个针对不同监听接口的listener重载方法(比如适配StepExecutionListener、ChunkListener、ItemReadListener等不同类型监听器的重载),你自定义的StopListener继承了StepListenerSupport,同时实现了多个监听接口,直接传入实例时编译器无法匹配到对应的重载方法,因此抛出方法歧义错误。
解决方案
- 方案1:强转实例为对应接口类型,分开注册
你用到的beforeStep属于StepExecutionListener接口规范,afterChunk属于ChunkListener接口规范,分别明确类型注册即可:
@Bean public Step dataFilterStep() { StopListener stopListener = new StopListener(); return stepBuilderFactory.get("dataFilterStep") .<UserInfo, UserInfo> chunk(10) .reader(dataFilterItemReader()) .processor(dataFilterItemProcessor()) .writer(dataFilterWriter()) .listener((StepExecutionListener) stopListener) .listener((ChunkListener) stopListener) .build(); }
- 方案2:使用明确的专属注册方法
Spring Batch的StepBuilder提供了不同类型监听器的专属注册入口,不需要走通用的listener方法,避免歧义:
@Bean public Step dataFilterStep() { StopListener stopListener = new StopListener(); return stepBuilderFactory.get("dataFilterStep") .<UserInfo, UserInfo> chunk(10) .reader(dataFilterItemReader()) .processor(dataFilterItemProcessor()) .writer(dataFilterWriter()) .stepExecutionListener(stopListener) .chunkListener(stopListener) .build(); }
- 方案3:添加
@StepListener注解
给自定义的StopListener类上加@StepListener注解,将监听器注册为Spring Bean,注入到Step配置中即可自动识别类型:
@StepListener @Component public class StopListener extends StepListenerSupport{ // 原有逻辑不变 }
配置里直接注入即可:
@Autowired private StopListener stopListener; @Bean public Step dataFilterStep() { return stepBuilderFactory.get("dataFilterStep") .<UserInfo, UserInfo> chunk(10) .reader(dataFilterItemReader()) .processor(dataFilterItemProcessor()) .writer(dataFilterWriter()) .listener(stopListener) .build(); }
优化提示
你当前的超时判断基于Job的启动时间,如果需要按Step的运行时长做超时控制,可以直接取StepExecution的startTime计算,按需调整即可。
内容的提问来源于stack exchange,提问作者Thomson Mathew
相关产品推荐
相关产品推荐

