Mr.H.
Mr.H.

Reputation: 1055

Spring SpEL access Configuration-Bean

I am working in a legacy software where most of the configuration is externalized from application.properties it resides in a file called custom.properties which will be read into a configuration bean that is declared like that.

@Configuration
@ConfigurationProperties(locations = "classpath:custom.properties", ignoreUnknownFields = true, prefix = "custom")
public class CustomProperties {
...
}

This application has some scheduled tasks, which where declared to work at a fixed interval and time. @Scheduled(cron = "0 0 16 * * 3") Until now everything works fine. Recently I have been asked to make this cronjob happen at a configurable time. So I added another property to custom.properties and an attribute to CustomProperties (including getter and setter). Next I altered the scheduled annotation to look like this. @Scheduled(cron = "${@customProperties.cronJob1Schedule}")

When I start the application I get the following exception:

java.lang.IllegalStateException: Encountered invalid @Scheduled method 'cronJob1': Could not resolve placeholder '@customProperties.cronJob1Schedule' in string value "${@bwvProperties.cronJob1Schedule}"
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:406)
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:282)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)

Has anybody had that issue before? Why cant I access the configuration bean in SpEL?

Upvotes: 6

Views: 9905

Answers (2)

Pavel Horal
Pavel Horal

Reputation: 18204

Be careful that there are two distinct mechanisms that work on string values processed by Spring:

Property resolution - ${my.property}

Spring is able to replace placeholders ${placeholder} with values from configured property sources. This proces simply replaces string key with a string value (and runs it through a converter if needed).

Spring Expression Language evaluation - #{spel.expression}

Spring is able to run contents of #{} through SPeL interpretter. This offers much more powerful tool as you can interact with your application code from inside your expression, e.g. by getting property from one of your bean #{@cumstomProperties.cronJob1Schedule}.

TL;DR

You just need to switch ${ for #{ in your annotation value.

Upvotes: 9

Robin-Hoodie
Robin-Hoodie

Reputation: 4974

I believe you've made a typo, assuming you're injecting your config properties similar to this:

@Autowired private CustomProperties bwvProperties

It should be #{bwvProperties.cronJob1Schedule} - drop the @, change $ by #

Upvotes: 1

Related Questions