如何在Spring Batch Tasklet中获取任务执行时间及解决request未定义问题
解决方案
1 核心问题说明
你的代码中没有声明或注入HttpServletRequest类型的request变量,所以编译器会识别到变量未定义报错。同时你现有的时长统计逻辑存在逻辑错误:beforeStep是步骤执行前的回调,你在该方法内直接计算结束时间,此时业务逻辑尚未运行,得到的时长完全不符合预期。
2 修复方案
方案1:保留从request取startTime的逻辑
需要先将当前类交给Spring容器管理,再注入HttpServletRequest对象,同时调整时长统计的执行时机:
@Component // 必须添加,让Spring管理该Bean才可注入依赖 public class FpTxnGenerateVoucherHeader implements Tasklet, StepExecutionListener { // 注入HttpServletRequest对象 @Autowired private HttpServletRequest request; // 定义成员变量存储开始时间 private long startTime; @Override public void beforeStep( StepExecution stepExecution) { // 步骤执行前仅记录开始时间 this.startTime = (Long) request.getAttribute("startTime"); } // 实现afterStep回调,步骤执行完成后计算时长 @Override public ExitStatus afterStep(StepExecution stepExecution) { long endTime = System.currentTimeMillis(); long executeTime = endTime - startTime; log.info("Tasklet执行时长:{}ms", executeTime); return stepExecution.getExitStatus(); } // 省略Tasklet接口的execute方法实现 }
方案2:无request依赖的更优实现(推荐)
直接使用Spring Batch自带的ExecutionContext存储开始时间,避免和Web层耦合,适配非Web触发的批量任务场景:
public class FpTxnGenerateVoucherHeader implements Tasklet, StepExecutionListener { private static final String START_TIME_KEY = "taskStartTime"; @Override public void beforeStep( StepExecution stepExecution) { // 直接在步骤上下文中存储开始时间 stepExecution.getExecutionContext().putLong(START_TIME_KEY, System.currentTimeMillis()); } @Override public ExitStatus afterStep(StepExecution stepExecution) { long startTime = stepExecution.getExecutionContext().getLong(START_TIME_KEY); long executeTime = System.currentTimeMillis() - startTime; log.info("Tasklet执行时长:{}ms", executeTime); return stepExecution.getExitStatus(); } // 省略Tasklet接口的execute方法实现 }
内容的提问来源于stack exchange,提问作者user16750862
相关产品推荐
相关产品推荐

