5

This question is possibly a duplicate of this older question.

I'm working on a Spring Boot 1.4 application and I have a method of a bean annotated with @Scheduled. I need to pass the cron value to the annotation and, since I'm using YAML based configuration, the cron value is stored in the YAML file (application.yaml).

I can't find a way to pass the property value app.cron to the annotation.

For instance, this doesn't work

@Scheduled(cron = ${app.cron})

I have also tried to use EL expression, but no luck.

What is the proper way to pass a YAML based property value to a Spring annotation?

Community
  • 1
  • 1
Luciano
  • 847
  • 1
  • 11
  • 23

2 Answers2

6

Try putting it in a Javaconfig first and it should work with EL:

@Configuration
@ConfigurationProperties(prefix = "app")
public class CronConfig {
    private String cron;
    
    @Bean
    public String cron() {
        return this.cron;
    } 

    public void setCron(String cron) {
       this.cron = cron;
    }
}

And use it with @Scheduled(cron = "#{@cron}")

I didn't tried this for scheduled Taks but I had similar problem with injecting something to an annotation.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
Dennis Ich
  • 3,585
  • 6
  • 27
  • 44
  • I already have a class annotated with @ConfigurationProperties, which stores the properties from the yAML file. Do you think the class name makes any difference. If I use EL, I get "bean not found". Also, can you provide the EL expression that you have used? – Luciano Sep 22 '16 at 15:23
  • ```@Configuration``` properties does not make the properties public to all other components. ```@Config```and ```@Bean``` are the ones adding them to your context. If you just have ```@ConfigurationProperties``` the properties are only bound to the specific component. – Dennis Ich Sep 22 '16 at 15:29
  • the EL I used was this: ```#{@beanName}``` – Dennis Ich Sep 22 '16 at 15:30
  • I use the @EnableConfigurationProperties on the Config class, and it works fine. I can access the properties in a type-safe way from every other class. What's the complete path of the Config annotation? I can't find it. – Luciano Sep 22 '16 at 15:34
  • its @Configuration sorry I will update it was written from memory. I will update the answer. – Dennis Ich Sep 22 '16 at 15:39
  • that did the trick. It's weird because I can inject the configuration class in Spring managed beans using autowired without the Configuration annotation. Thanks! – Luciano Sep 22 '16 at 15:43
3

You can also do this:

@Configuration
public class CronConfig() {

    @Value("${app.cron}")
    private String cronValue;

    @Bean
    public String cronBean() {
        return this.cronValue;
    } 
}

And use it with @Scheduled(cron = "#{@cronBean}")

In this case you'll get the value of "app.cron" from Spring's application.properties or application.yml, the one that you've configured in your project.

Note:

There is a little mistake in the code posted by Dennis:

The method cron() is calling itself:

@Bean
public String cron() {
    return this.cron(); // It's calling itself
}

So if you run this code you will get and StackOverFlow Exception.

Carlos Zegarra
  • 188
  • 1
  • 5