将外部化值注入 Spring 注解

2022-01-13 00:00:00 annotations spring java spring-scheduled

我一直在考虑在编译时评估注释值的 Java 特性,它似乎确实很难将注释值外部化.

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.

更重要的是,我正在尝试外部化一个注释值,该值控制 Spring 中计划的方法调用之间的延迟,例如:

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
    }
}

假设 scheduling.properties 在类路径中,并且包含属性键 delayValue 及其对应的 long 值.

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

现在,这段代码有明显的编译错误,因为我们试图为 final 变量赋值,但这是强制性的,因为我们不能将变量赋值给注释值,除非它是静态最终.

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.

有没有办法解决这个问题?我一直在思考 Spring 的自定义注解,但根本问题仍然存在——如何将外部化的值分配给注解?

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?

欢迎提出任何想法.

一个小更新 - 对于这个例子来说,Quartz 集成是多余的.我们只需要以亚分钟级的分辨率定期执行,仅此而已.

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

推荐答案

Spring v3.2.2 中的 @Scheduled 注解在原来的 3 个 long 参数中添加了 String 参数来处理这个问题.fixedDelayStringfixedRateStringinitialDelayString 现在也可用:

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
 }

相关文章