如何使用@PostConstruct 仅在一个实例中调用@Scheduled 方法

问题描述

  1. 有工作需要按 cron 计划完成
  2. 必须在spring boot应用程序启动时执行与作业中相同的逻辑,因此使用@postconstruct方法
  3. 使用了 Shedlock,因为它计划在多个实例中运行应用程序

问题是:如何让@postconstruct 方法的逻辑只在一个实例中调用而在其他实例中不调用

我的代码示例:

@Component
@AllArgsConstructor
public class TestJob {

    private TestService testService;

    @postconstruct
    public void init() {
        testService.upload();
    }
    
    @Scheduled(cron = "${cron}")
    @SchedulerLock(name = "uploadJob",lockAtMostFor = "${lockAtMostFor}")
    public void execute() {
        testService.upload();
    }
}

解决方法

如果您将 @PostConstruct 方法置于不同的服务并调用 execute() 方法,它应该可以工作。

原因是 ShedLock 默认使用 Spring AOP,它将 @SchedulerLock 标记的每个方法包装在一个方面进行锁定。如果在同一个类中调用另一个方法,通常不会应用 Spring AOP。