1
votes

I have got a Spring application that uses

@SpringBootApplication

and

@EnableScheduling

in the main java. Also it has a class with several @Scheduled methods:

@Component

public class ScheduledTasks {

(...)

@Scheduled(cron = "0 0/5 10-18 ? * *")    
public void doThings() {
(...)
}

@Scheduled(cron = "0 0/22 23 ? * *")    
public void doAnotherThings() {
(...)
}

As far as I know it does not declare any special Pool of Threads, ThreadPoolExecutor or things like that. The app works ok and the scheduled jobs run ok.

I would like to get the values of the @Scheduled anotation at runTime, just to know when the cron was defined and show the info to the user.

It is NOT necesary to change or add new task/jobs to the scheduler.

I have been trying some ideas in thi answer How are Spring <task:scheduled> objects represented at runtime? trying to get a autowired ThreadPoolExecutor or ThreadPoolTaskExecutor and then trying to see if a field of that object has usefull info but geting them with Autowired always fails when the application starts.

My app also says when starting "No TaskScheduler/ScheduledExecutorService bean found for scheduled processing", so I suppose it is using a default/easy way to run the scheduled methods, they work ok.

I dont know if it necesary to manually create a @Bean with that object in a @Configuration class to instrospect it, or how to fill the constructor asociated with them.

What object has the info asociated with the schedule jobs?

Can I autowire it in my own class to get the info?

Is it necesary to manually create it using @Bean in Spring ? How?

Thanks a lot.

2
Why don't you take that strings out to the application.properties? - Ken Bekov

2 Answers

1
votes

Annotations are considered to be metadata of your code. You should not interact with annotations - only the providing library should. But just externalize the cron expression of interest and read it somewhere else.

@Scheduled(cron = "${yourConfiguration.cronExpression}")
someMethod()...

@Value("${yourConfiguration.cronExpression}")
String cronExpression;  // injected for debugging purposes

You also might be able to get hold of the TaskScheduler and make it list all tasks including all cron expressions. But this will be outside the context of your method in question.

0
votes

Since Spring 5.0.2 , it allows to get the schedule task information at runtime :

I've currently got this as a Set getScheduledTasks() method on ScheduledAnnotationBeanPostProcessor, with ScheduledTask exposing a Task getTask() method now. You may check the type of the task then, and for easier discovery, I've also introduced specific FixedRateTask and FixedDelayTask subclasses which you may then check for next to CronTask, not requiring any extra metadata beyond the Task instance itself.

I'll have one more pass through it; to be committed tonight.

The ScheduledTask are stored inside the ScheduledAnnotationBeanPostProcessor bean . You can get them from this bean and cast it to CronTask to get the cron expression:

@Component
public class SchedulederInfo {

   @Autowired
   private ScheduledAnnotationBeanPostProcessor scheduledBpp;

   public void printInfo(){
        for(ScheduledTask task : scheduledBpp.getScheduledTasks()) {
          Task t = task.getTask();
          if(t instanceof CronTask) {
              CronTask cronTask = (CronTask)t;
              System.out.println(cronTask.getRunnable());   //print the schedule method name 
              System.out.println(cronTask.getExpression()); //print the cron expression
          }
   }
}