2

I am trying to make use of Spring Boot AutoConfigured @EnableScheduling to create a cron job. Job triggers perfectly fine if the fixedRateString is hardcoded. However it does not succeed if I try to make use of SpEL to supply the value.

//Bean Instantiation in JavaConfig

@Bean
public AlertbotJob2 getAlertJob2() {
    AlertbotJob2 alertbotJob2 = new AlertbotJob2("alertId", "alertName", "alertSubject", "6000", true);
    return alertbotJob2;
}

Bean Definition

public class AlertbotJob2 {

String alertId;
String alertName;
String alertSubject;
public String cronPattern;
boolean isActive;

public AlertbotJob2() {
}

public AlertbotJob2(String alertId, String alertName, String alertSubject, String cronPattern, boolean isActive) {
    super();
    this.alertId = alertId;
    this.alertName = alertName;
    this.alertSubject = alertSubject;
    this.cronPattern = cronPattern;
    this.isActive = isActive;
}

@Scheduled(initialDelay = 60000, fixedRateString = "#{this.cronPattern}")
public void doTheJob() {
    System.out.println("DoSomething");
}

}

Exception is :: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'this' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?

I am just trying to set the trigger values dynamically. Please help.

4 Answers 4

1

I don't think you can use SpEL like this. Maybe the better approach is to define your cron pattern in some property like:

myapp.scheduler.cronPattern=...

And then use the following syntax:

@Scheduled(cron = "${myapp.scheduler.cronPattern}")
public void doTheJob() {
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can't use this there.

You have to do it by bean name @someBean.cronPattern.

2 Comments

Well, I tried that approach but did not work well. As I am programmatic ally creating the beans after reading database configurations. Need to figure out if @someBean.cronPattern can be created with prototype scope ..
No; there is no way for the SpEL expression to directly refer to the instance of the class in which the annotation resides.
0

Solution 1: use the hardcoded pattern if its already known @Scheduled(cron = "0 0/5 * * * MON-FRI")

Solution 2: If the pattern is available in some property @Scheduled(cron = "${myapp.scheduler.cronPattern}")

Solution 3 : This approach does not use annotation. Instead the Beans are just implemented as runnables And then override the SchedulingConfigurer.configureTasks() to dynamically set the schedules using taskRegistrar.addCronTask(urRunnableJob, urCronPatternFromDB); . Cron pattern is stored in database table, initialize it as properties as below.

class AppConfig { 

    @Autowired
    ConfigurableEnvironment environment;

    private void initPropertiesMap() {
        environment.getPropertySources()
            .addLast(new MapPropertySource("myAppProperties", myAppProperties.getProperties())); // Prior DAO call required to read the configs from database
    }

    @PostConstruct
    public void postConstruct() {
        initPropertiesMap();
    }

}

Comments

0

you can try this:

   e.g @Value("#{T(com.someName.ClassName).cronPattern}")

I reference this Accessing static variable in spring annotations using spel

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.