I am using @Scheduled for simple scheduling of a job every 30 seconds.
I wanted to use @Scheduled(fixedDelay=30000) but have a requirement that all configuration must be externalized.
The problem is that the fixedDelay parameter is a long type - and if I write @Scheduled(fixedDelay="${myconfig.delay}") I will get a NumberFormatException because the ${myconfig.delay} evaluates to a String - I get the same error if I use #{myconfig.delay}. So for some reason Springs type conversion is not in effect when I use SpEL inside the @Scheduled annotation.
The expression is valid and SpEL can do the type conversion if I use the @Value annotation. This works beautifully and my String property is converted to a long:
(If I use ${myconfig.delay} I will get a NumberFormatException since Spring will then just try and set the String value directly - so SpEL is clever enough to do the type conversion in that scenario)Code:@Value("#{myconfig.delay}") private long delay;
However, I cannot use @Value inside @Scheduled so that is not an option. The workaround I have found instead, is to use the "cron" attribute value of @Scheduled annotation since "cron" is of type String:
"config.timerTaskCron" is defined in a properties file like:Code:@Scheduled(cron = "${config.timerTaskCron}") public void run() { System.out.println("Running job"); }
config.timerTaskCron=*/30 * * * * *
However our users look a bit timid when we throw cron expressions at them - also since the schedule is so simple we don't really have a specific need to use cron.
Is there a way other than using XML configuration of the scheduled tasks that allows me to externalize the configuration of fixedDelay/fixedRate or other non-string parameters on annotations like @Scheduled - e.g. by using SpEL?


Reply With Quote