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.
The
valueattribute of a@Valueannotation 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 thedynamicSPELStrstring:Explanation of error
SpEL expressions use
#variableNameto access a variable (see SpEL documentation, section 4.3.10. Variables).Since the beginning of
dynamicSPELStris#{, 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({)'"