【问题标题】:Trying to set cron property of @Scheduled from property file using @Value but getting compile time error尝试使用 @Value 从属性文件设置 @Scheduled 的 cron 属性,但出现编译时错误
【发布时间】:2020-08-29 05:45:23
【问题描述】:

我一直在尝试将@Scheduled 的 cron 属性设置如下。

public class ObjectScheduler {
  @Value("${config.cron.expression}")
  private static final CRON_EXPRESSION;

  @Scheduled(cron = CRON_EXPRESSION, zone="GMT")
  public void scheduledObjectFetch() {...}
}

我在这里遇到编译时错误

The value for the annotation attribute Scheduled.cron attribute must be a constant expression.

如果我直接在属性中给出表达式,同样的事情会起作用

@Scheduled(cron = "${config.cron.expression}", zone="GMT")

这里的值也是在运行时从配置中分配的,所以为什么这里没有给出编译时错误?为什么当我使用 @Value 注释将它分配给变量时,它不认为它是一个常量表达式?有什么我想念的吗?是因为Java还是Spring的@Value注解?

【问题讨论】:

    标签: java spring cron spring-scheduled


    【解决方案1】:

    Spring 不会将 @Value 插入静态字段,尽管它可以通过 setter 完成。

    这也适用于需要在编译时定义的static final字段。

    所以你不能通过@Value配置CRON_EXPRESSION,只有硬编码才能工作:

    private static final String CRON_EXPRESSION = "0 0 8 * * ?";
    
    @Scheduled(cron = CRON_EXPRESSION, zone="GMT")
      public void scheduledObjectFetch() {...}
    

    【讨论】:

    • 有没有办法通过属性文件设置它,保持可配置而不是硬编码?
    【解决方案2】:

    在您的情况下,您将字段设置为 final 您无法使用 @value 将值注入字段的最根本原因是 Java 用实际值替换了代码中出现的静态最终“变量” (因为它在编译时当然是已知的)。因此,如果您删除 final 限定符,它应该适用于您使用 spring setter 注入。您不能使用 @value 将属性文件中的值注入到 static final 变量中,这是因为 java 处理最终静态变量的方式。

    理想情况下,我们可以使用 spring 表达式property 文件中填充 cron,方法是:

    @Component("scheduledAnnotationObjectScheduler")
    public class ObjectScheduler {
      @Scheduled(cron = "${cron.expression}")
      public void scheduledObjectFetch() {...}
    }
    

    application.properties

    cron.expression=0 15 10 15 * ?
    

    这应该从理论上解析属性文件中的cron 值,因为它是在组件扫描期间拾取的。

    【讨论】:

      猜你喜欢
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 1970-01-01
      • 2017-12-10
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多