You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何识别Spring Batch任务是由控制器还是调度器触发?

解决方案:通过JobParameters区分触发来源并动态切换SQL

核心思路是向Spring Batch任务传递标识触发来源的JobParameter,然后在任务配置中根据该参数动态选择对应的SQL查询。具体实现步骤如下:

1. 触发任务时传递来源标识参数

无论是控制器手动触发还是调度器定时触发,在启动Job时都要添加一个triggerSource参数,明确标记触发来源。

控制器触发示例

@RestController
@RequestMapping("/batch")
public class BatchController {

    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job myBatchJob;

    @PostMapping("/trigger")
    public ResponseEntity<String> triggerJob() throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("triggerSource", "controller")
                .addLong("timestamp", System.currentTimeMillis()) // 确保每次任务实例唯一
                .toJobParameters();

        jobLauncher.run(myBatchJob, jobParameters);
        return ResponseEntity.ok("Job triggered from controller");
    }
}

调度器触发示例

@Component
public class BatchScheduler {

    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job myBatchJob;

    @Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行
    public void scheduleJob() throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("triggerSource", "scheduler")
                .addLong("timestamp", System.currentTimeMillis())
                .toJobParameters();

        jobLauncher.run(myBatchJob, jobParameters);
    }
}

2. 在任务配置中根据参数动态选择SQL

使用@StepScope注解让ItemReader能够访问StepExecution中的JobParameters,从而根据triggerSource的值切换SQL。

动态SQL的ItemReader配置示例

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    @StepScope
    public JdbcCursorItemReader<MyEntity> itemReader(@Value("#{stepExecution.jobExecution.jobParameters['triggerSource']}") String triggerSource) {
        JdbcCursorItemReader<MyEntity> reader = new JdbcCursorItemReader<>();
        reader.setDataSource(dataSource);
        reader.setRowMapper(new BeanPropertyRowMapper<>(MyEntity.class));

        // 根据触发来源设置不同SQL
        if ("controller".equals(triggerSource)) {
            reader.setSql("SELECT id, name, status FROM my_table WHERE status = 'PENDING' AND trigger_type = 'MANUAL'");
        } else if ("scheduler".equals(triggerSource)) {
            reader.setSql("SELECT id, name, status FROM my_table WHERE status = 'PENDING' AND trigger_type = 'SCHEDULED'");
        } else {
            // 默认SQL(可选)
            reader.setSql("SELECT id, name, status FROM my_table WHERE status = 'PENDING'");
        }

        return reader;
    }

    // 其他Step、Job配置省略...
}

3. 注意事项

  • 必须添加唯一参数(如timestamp):Spring Batch不允许使用相同的JobParameters重复启动同一个Job,所以每次触发都要加一个唯一值(比如时间戳)来保证任务实例的唯一性。
  • @StepScope的作用:只有标记为@StepScope的bean才能访问stepExecution上下文,从而获取JobParameters。
  • 参数校验:可以在配置中添加对triggerSource参数的校验,避免非法值导致SQL错误。

内容的提问来源于stack exchange,提问作者Aniruddha Gayake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:10:35