Reputation: 6281
Using Sprint Boot 2.0.4.RELEASE, I have the following properties class (simplified):
@Configuration
@EnableConfigurationProperties(MyOtherHierarchicalNonConstantProperties.class)
public class AppConfiguration {
public static final String MY_CONSTANT = "${path.to.my-constant}";
}
and the application.yml
(also simplified):
path.to.my-constant: mystring
The value from application.yml
never gets assigned to MY_CONSTANT
, which is required for use as an argument to annotations. (I want all configurable options between build environments to be set in application.yml
!) The value of MY_CONSTANT
ends up being ${path.to.my-constant}
.
I have been working with this issue for pretty much the entire day, also tried several different options after lots of searching, such as:
${${path.to.my-constant}}
#1#{${path.to.my-constant}}
#2${#{path.to.my-constant}}
#{'${path.to.my-constant}'}
In some cases I get the exact expression as the value of the string (as said above), but in some cases I get exceptions such as:
IllegalArgumentException
from PropertyPlaceholderHelper.parseStringValue
saying Could not resolve placeholder 'mystring' in value "${${path.to.my-constant}}"
SpelEvaluationException
from PropertyOrFieldReference.readProperty
saying EL1008E: Property or field 'mystring' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
Both indicating that if the initial expression is further wrapped inside other SpEL braces, the inner expression gets translated to the desired value. But after that, it refuses to be extracted from the outer braces. (For quite a long time, I was trying hundreds of SpEL operations to try and somehow "extract" the value from the outer braces...)
One thing I had also tried, is moving the constant into the other properties class with the @ConfigurationProperties
annotation hoping it would change something, but the results seem to be identical.
I know the question about assigning configuration properties to constants in Spring Boot has been asked a lot, I have also tried every option on planet Earth after coming here to ask this and am hopelessly lost.
Someone please, for once and for all, put and end to this miserable lack of single source of truth about configurable constant expressions and tell us how to do this the right way! (And if Spring Boot never intended for it to be possible, that information could also be helpful to know...)
PS! No nasty hacks please...
Upvotes: -1
Views: 6501
Reputation: 435
Annotations that reference a field property that is be both static & final. If you're using the Spring boot annotations (e.g. @Value, @Scheduled, etc); then just use the spel. Or if you needs to use @Autowired, make variables into beans (or a bean, your preference) and use autowire them to a factory service to create your objects.
But it looks like you're using @CrossOrigin which does not seem to handle spel & a factory doesn't quite fit this use case. So you're going to need to add to your configuration, like so
@Configuration
public class CrossConfig{
private String[] crossEndPoints = ...;
@Bean
public WebMvcConfigurer corsConfigurer(@Value("${path.to.my-constant}") String crossOrigin) {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
for(String endpoint : crossEndPoints){
registry.addMapping(endpoint).allowedOrigins(crossOrigin);
}
}
};
}
}
As seen in SpringDocs for CrossOrigins. You're just going to need to manually list your endpoints, or programmatically find them some way. If you already have a WebMvcConfigurer bean, just added the addCorsMappings(CorsRegistry) to it.
Upvotes: 0
Reputation: 2073
I think, for you this is the best possible option:
@Configuration
@EnableConfigurationProperties(prefix = "path.to")
public class AppConfiguration {
public final String MY_CONSTANT;
public UserService(@Value("${path.to.MY_CONSTANT}") String MY_CONSTANT) {
this.MY_CONSTANT= MY_CONSTANT;
}
}
Can you try this and let me know..
Upvotes: -1
Reputation: 497
@anddero...it will help you...
@Configuration
@EnableConfigurationProperties(MyOtherHierarchicalNonConstantProperties.class)
public class AppConfiguration {
public static final String MY_CONSTANT = "${path.to.my-constant}";
@Autowired
public AppConfiguration (@Value("${path.to.my-constant}") String MY_CONSTANT ) {
this.MY_CONSTANT = MY_CONSTANT ;
}
}
Upvotes: -2