Is it possible to call a spring scheduled method manually

marvin picture marvin · May 3, 2018 · Viewed 9.8k times · Source

Is there a way to call a spring scheduled method (job) through a user interaction? I need to create a table with shown all jobs and the user should be able to execute them manually. For sure the jobs run automatically but the user should be able to start them manually.

@Configuration
@EnableScheduling
public class ScheduleConfiguration {

    @Bean
    public ScheduledLockConfiguration taskScheduler(LockProvider 
     lockProvider) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(lockProvider)
                .withPoolSize(15)
                .withDefaultLockAtMostFor(Duration.ofHours(3))
                .build();
    }

    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }
}

@Component
public class MyService {

    @Scheduled(fixedRateString = "1000")
    @SchedulerLock(name = "MyService.process", lockAtLeastFor = 30000)
    @Transactional
    public void process() {
        // do something
    }
}

Answer

das Keks picture das Keks · Oct 29, 2018

Here's an example using a TaskScheduler:

Creating a task which will be scheduled and invoked manually:

@Component
public class SomeTask implements Runnable {

    private static final Logger log = LoggerFactory.getLogger();

    @Autowired
    public SomeDAO someDao;

    @Override
    public void run() {
        // do stuff
    }
}

Creating TaskScheduler bean:

@Configuration
public class TaskSchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
        return threadPoolTaskScheduler;
    }
}

Scheduling task for periodic execution:

@Component
public class ScheduledTasks {
    @Autowired private TaskScheduler taskScheduler;

    // Tasks
    @Autowired private SomeTask task1; // autowired in case the task has own autowired dependencies
    @Autowired private AnotherTask task2;

    @PostConstruct
    public void scheduleTasks() {
        taskScheduler.schedule(task1, new PeriodicTrigger(20, TimeUnit.SECONDS));
        taskScheduler.schedule(task2, new CronTrigger("0 0 4 1/1 * ? *"));
    }
}

Manually invoking a task via a http request:

@Controller
public class TaskController {

    @Autowired private TaskScheduler taskScheduler;

    // Tasks
    @Autowired private SomeTask task1;

    @RequestMapping(value = "/executeTask")
    public void executeTask() {
        taskScheduler.schedule(task1, new Date()); // schedule task for current time
    }
}