Injecting externalized value into Spring annotation

quantum picture quantum · Jul 23, 2012 · Viewed 47.8k times · Source

I've been thinking around the Java feature that evaluates annotation values in compile-time and it seems to really make difficult externalizing annotation values.

However, I am unsure whether it is actually impossible, so I'd appreciate any suggestions or definitive answers on this.

More to the point, I am trying to externalize an annotation value which controls delays between scheduled method calls in Spring, e.g.:

public class SomeClass {

    private Properties props;
    private static final long delay = 0;

    @PostConstruct
    public void initializeBean() {
        Resource resource = new ClassPathResource("scheduling.properties");
        props = PropertiesLoaderUtils.loadProperties(resource);
        delay = props.getProperties("delayValue");
    }

    @Scheduled(fixedDelay = delay)
    public void someMethod(){
        // perform something
    }
}

Suppose that scheduling.properties is on classpath and contains property key delayValue along with its corresponding long value.

Now, this code has obvious compilation errors since we're trying to assign a value to final variable, but that is mandatory, since we can't assign the variable to annotation value, unless it is static final.

Is there any way of getting around this? I've been thinking about Spring's custom annotations, but the root issue remains - how to assign the externalized value to annotation?

Any idea is welcome.

EDIT: A small update - Quartz integration is overkill for this example. We just need a periodic execution with sub-minute resolution and that's all.

Answer

Mark-A picture Mark-A · May 9, 2013

The @Scheduled annotation in Spring v3.2.2 has added String parameters to the original 3 long parameters to handle this. fixedDelayString, fixedRateString and initialDelayString are now available too:

 @Scheduled(fixedDelayString = "${my.delay.property}")
 public void someMethod(){
        // perform something
 }