Search code examples
spring-bootschedulerpostconstructshedlockmulti-instance-deployment

How to call @Scheduled method in only one instance using @PostConstruct


  1. There is job that needs to be done on cron schedule
  2. The same logic as in the job must be performed at the start of the spring boot application, therefore @PostConstruct method is used
  3. Shedlock is used, since it is planned to run the application in multiple instances

The question is: how to make the logic from the @PostConstruct method be called in only one instance and not called in others?

An example of my code:

@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();
    }
}

Solution

  • It should work if you put the @PostConstruct method to a different service and call the execute() method.

    The reason is that ShedLock by default uses Spring AOP which wraps each method marked by @SchedulerLock in an aspect that does the locking. And Spring AOP usually does not get applied if you call another method in the same class.