Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use Spring-EL in @Value when using constants to resolve a property

I'm trying to use a constant to define a property and then resolving it with the @Value annotation.

I defined the constant in an interface:

public interface InternalConstant{
   public static final String JOB_NAME_PROPERTY = "javabatch.jobName";
}

I'm using springboot and I'm adding the property as a default property to the context:

SpringApplication springApp = new SpringApplication(configs.toArray());
Properties props = new Properties();
props.setProperty(InternalConstants.JOB_NAME_PROPERTY, "MyStartableJob");
springApp.setDefaultProperties(props);

Now, I'd like to use @Value to inject the String "MyStartableJob" into a String. But instead of directly using @Value(value="${javabatch.jobName}), I'd like to use the defined constant.

I tried

@Value(value="#{T(ch.mobi.javabatch.core.internal.InternalConstants).JOB_NAME_PROPERTY}")

But of course, this resolves only to "javabatch.jobName" and not to the value of the property named "javabatch.jobName".

So I tried to wrap it in @Value(value="${#{T(ch.mobi.javabatch.core.internal.InternalConstants).JOB_NAME_PROPERTY}}"), but this causes an exception.

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder '#{T(ch.mobi.javabatch.core.internal.InternalConstants).JOB_NAME_PROPERTY}' in string value "${#{T(ch.mobi.javabatch.core.internal.InternalConstants).JOB_NAME_PROPERTY}}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204)
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:175)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:801)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:955)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 16 more

I know, that I could simply inject the Environment and using its getProperty method:

@Autowired
private Environment env;

public void m1() {
    env.getProperty(InternalConstants.JOB_NAME_PROPERTY);
}

This works and serves my purpose. But I wonder, if this could also be done using SPEL in @Value.

Thanks.

like image 791
Hansjoerg Wingeier Avatar asked Jun 02 '15 12:06

Hansjoerg Wingeier


People also ask

What is the use of @value annotation in spring?

Spring @Value annotation is used to assign default values to variables and method arguments. We can read spring environment variables as well as system variables using @Value annotation. Spring @Value annotation also supports SpEL. Let's look at some of the examples of using @Value annotation.

How set value in properties file in spring?

To change properties in a file during runtime, we should place that file somewhere outside the jar. Then we tell Spring where it is with the command-line parameter –spring. config. location=file://{path to file}.

What is @configuration in spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.


2 Answers

What about the simplest approach:

@Value("${" + InternalConstant.JOB_NAME_PROPERTY + "}")
private String jobName
like image 50
Pavel Horal Avatar answered Oct 15 '22 09:10

Pavel Horal


You can access the property referenced by the constant using environment directly in the SpEL expression and the correct value should be injected:

@Value("#{environment.getProperty(T(com.example.InternalConstants).JOB_NAME_PROPERTY)}")
private String jobName;
like image 43
Bohuslav Burghardt Avatar answered Oct 15 '22 08:10

Bohuslav Burghardt