Search code examples
javaspringspring-bootscheduled-tasksspring-scheduled

Is there way to use @Scheduled together with Duration string like 15s and 5m?


I have following annotation in my code

@Scheduled(fixedDelayString = "${app.delay}")

At this case I have to have properties like this

app.delay=10000 #10 sec

Propery file looks unreadable because I have calculate value to miliseconds.

Is there way to pass value like 5m or 30s there ?


Solution

  • As far as I know, you can't do it directly. However, Spring boot configuration properties do support automatic conversion of parameters like 15s and 5m to Duration.

    This means you could create a @ConfigurationProperties class like this:

    @ConfigurationProperties("app")
    public class AppProperties {
        private Duration delay;
    
        // Setter + Getter
    }
    

    Additionally, since you can use bean references with Spring's Expression Language within the @Scheduled annotation, you can do something like this:

    @Scheduled(fixedDelayString = "#{@'app-com.xyz.my.pkg.AppProperties'.delay}")
    public void schedule() {
        log.info("Scheduled");
    }
    

    Note: When you use @EnableConfigurationProperties or @ConfigurationPropertiesScan, the configurationproperties beans are registered with the name <prefix>-<fully qualified classname>. So in the example above, I'm assuming that the AppProperties class is located in a package called com.xyz.my.pkg.

    If you don't like this, you can also use the @Component("beanName") annotation on top of the AppProperties class to give it a different bean name.


    Alternatively, you can programmatically add a task to the TaskScheduler. The benefit of that is that you have more compile-time safety.

    @Bean
    public ScheduledFuture<?> schedule(TaskScheduler scheduler, AppProperties properties) {
        return scheduler.scheduleWithFixedDelay(() -> log.info("Scheduled"), properties.getDelay());
    }