如何识别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
相关产品推荐
相关产品推荐

