Reputation: 107
I am trying to mimic the @Value
annotation programmatically by retrieving a property from the properties file using Environment
and then evaluate the expression using SpelExpressionParser
.
Here is a code snippet:
@Service
@Slf4j
public class Test {
private String dynamicSPELStr = "#{${test.spel.map}.default}";
@Autowired
private Environment environment;
void testSPEL() {
ExpressionParser parser = new SpelExpressionParser();
log.info("[PARSER] {}", parser
.parseExpression(environment.resolvePlaceholders(dynamicSPELStr))
.getValue());
}
}
and the property is: test.spel.map={default: '5', key1: '10', key2: '20', key3: '40'}
However I am receiving the following error:
Expression [#{{default: '5', key1: '10', key2: '20', key3: '40'}.default}] @1: EL1043E: Unexpected token. Expected 'identifier' but was 'lcurly({)'
Running the same expression using @Value
works just fine.
Upvotes: 2
Views: 4047
Reputation: 159096
The value
attribute of a @Value
annotation is not a SpEL expression. It supports placeholders using ${...}
, and it supports SpEL expressions using #{...}
.
It is only the text between #{
and }
that is a SpEL expression. As such, remove the #{
and }
from the dynamicSPELStr
string:
private String dynamicSPELStr = "${test.spel.map}.default";
Explanation of error
SpEL expressions use #variableName
to access a variable (see SpEL documentation, section 4.3.10. Variables).
Since the beginning of dynamicSPELStr
is #{
, the expression parser is complaining that the #
variable prefix isn't followed by a valid name-character, hence the error "Expected 'identifier' but was 'lcurly({)'"
Upvotes: 2