hello.wjx
hello.wjx

Reputation: 239

How to run Scheduled task after specific CommandLineRunner?

I do some initializations in a CommandLineRunner's run function and I want my Scheduled task to begin schedule after the initialization, how can I achive this?
For example, I have the CommandLineRunner:

@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        // Initializations
        // ...
    }
}

And the task scheduler:

public class SchedClass {
    @Scheduled(fixedRate = ONE_SECOND)
    public void sched() {
    }
}

What can I do to make sched() runs after run() runs?

Upvotes: 1

Views: 3388

Answers (2)

sanit
sanit

Reputation: 1764

class MySchedulingConfigurer implements SchedulingConfigurer {

    private ScheduledTaskRegistrar taskRegistrar;
    private IntervalTask task;

    public MySchedulingConfigurer(IntervalTask task) {
        this.task = task;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        this.taskRegistrar = taskRegistrar;
    }

    public void resume() {
        this.taskRegistrar.scheduleFixedRateTask(task);
    }

}

@Configuration
class SchedulerConfiguration {

    @Autowired
    private MySchedulingConfigurer schedulingConfigurer;

    @Bean
    public MySchedulingConfigurer mySchedulingConfigurer() {
        IntervalTask task = new IntervalTask(new MyTask(), 5000L);
        return new MySchedulingConfigurer(task);
    }

    public static class MyTask implements Runnable {

        @Override
        public void run() {
            System.out.println("===>  task executed...");
        }
    }

    @EventListener
    public void startScheduler(ApplicationReadyEvent event){
       schedulingConfigurer.resume();
    }
}


@Component
class CacheLoadingRunner implements CommandLineRunner {

    @Autowired
    private MySchedulingConfigurer schedulingConfigurer;

    @Override
    public void run(String... args) throws Exception {
        schedulingConfigurer.resume();
    }

}

Upvotes: 1

Nikolai  Shevchenko
Nikolai Shevchenko

Reputation: 7521

1) Add @EnableScheduling

@EnableScheduling
@SpringBootApplication
public class MyCommandLineRunner implements CommandLineRunner {
...
}

2) It makes no sense to denote Spring Boot application with @Component

UPDATED

It could be achieved manually. Provide a TaskScheduler

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

Inject it into MyCommandLineRunner along with SchedClass and run

@Component
public class MyCommandLineRunner implements CommandLineRunner {

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    @Autowired
    private SchedClass schedBean;

    @Override
    public void run(String... args) throws Exception {
        // ...
        taskScheduler.scheduleWithFixedDelay(() -> schedBean.sched(), ONE_SECOND);
        // ...
    }
}

Upvotes: 1

Related Questions