1

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.

1 Answers1

2

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({)'"

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Thanks a lot, now it's more clear. Now I am receiving a different error: `EL1008E: Property or field 'default' cannot be found on object of type 'java.util.Collections$UnmodifiableMap' - maybe not public or not valid? `. Any idea why that happens? – Mihai Catalin Valentin Jul 01 '21 at 09:39
  • @MihaiCatalinValentin No, but try `['default']` instead of `.default` – Andreas Jul 01 '21 at 09:53