spring-bootconfiguration-files

How to ignore expression checking in Spring boot config file


A Springboot project can't be started due to a config item like below

myconfig.properties
password=3#{xxxx|xxxx)?4/xxxxxxx+ABC1}

Error log

Caused by: org.springframework.expression.ParseException: Expression [3#{xxxx|xxxx)?4/xxxxxxx+ABC1}] @12: Found closing ')' at position 12 without an opening '('
    at org.springframework.expression.common.TemplateAwareExpressionParser.skipToCorrectEndSuffix(TemplateAwareExpressionParser.java:194) ~[spring-expression-6.1.4.jar:6.1.4]
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpressions(TemplateAwareExpressionParser.java:107) ~[spring-expression-6.1.4.jar:6.1.4]
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseTemplate(TemplateAwareExpressionParser.java:66) ~[spring-expression-6.1.4.jar:6.1.4]
    at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:52) ~[spring-expression-6.1.4.jar:6.1.4]
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1605) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1377) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:784) ~[spring-beans-6.1.4.jar:6.1.4]

How can I ignore the expression checking to avoid this failure?


Solution

  • The problem is that anything with #{ will get evaluated as SpEL expression which we want to avoid.

    Option 1: override SpEL prefix #{ to something else

    @Bean
    public BeanFactoryPostProcessor expressionResolverFactoryPostProcessor() {
        return beanFactory -> {
            StandardBeanExpressionResolver expressionResolver = new StandardBeanExpressionResolver();
            expressionResolver.setExpressionPrefix("#$#{");
            beanFactory.setBeanExpressionResolver(expressionResolver);
        };
    }
    

    By overriding the expression prefix as shown here, you avoid triggering SpEL expression parsing for anything that starts with #{


    Option 2: use nested string expression to avoid triggering parsing

    By wrapping your (NOT) expression into another expression you can avoid SpEL parsing:

    password=#{'4#{xxxx|xxxx)?4/xxxxxxx+ABC1}'}