如何通过Spring提供的EL表达式执行bean的属性或方法?

如何通过Spring提供的EL表达式执行bean的属性或方法?

关键两个bean:

org.springframework.expression.Expression

org.springframework.expression.spel.support.StandardEvaluationContext

实例:

java 复制代码
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.beans.factory.BeanExpressionException;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.context.expression.*;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.expression.spel.support.StandardTypeLocator;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestScope;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public final class CustomSpringBeanExpressionEvaluator {

    private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>(256);

    private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = new ConcurrentHashMap<>(8);

    private final ExpressionParser parser = new SpelExpressionParser();

    private BeanExpressionContext beanExpressionContext;

    public static Object evaluate(@NonNull String expression) {
        return SpringUtil.getBean(CustomSpringBeanExpressionEvaluator.class).doEvaluate(expression);
    }

    /**
     * SpringEL表达式解析
     *
     * @param expression - EL表达式
     */
    public Object doEvaluate(@NonNull String expression) {
        if (!StringUtils.hasLength(expression)) {
            return expression;
        }
        try {
            Expression expr = this.expressionCache.get(expression);
            if (expr == null) {
                expr = this.parser.parseExpression(expression, this.beanExpressionParserContext);
                this.expressionCache.put(expression, expr);
            }
            if (this.beanExpressionContext == null) {
                this.beanExpressionContext = new BeanExpressionContext(SpringUtil.getConfigurableBeanFactory(), new RequestScope());
            }
            StandardEvaluationContext sec = this.evaluationCache.get(beanExpressionContext);
            if (sec == null) {
                sec = new StandardEvaluationContext(beanExpressionContext);
                sec.addPropertyAccessor(new BeanExpressionContextAccessor());
                sec.addPropertyAccessor(new BeanFactoryAccessor());
                sec.addPropertyAccessor(new MapAccessor());
                sec.addPropertyAccessor(new EnvironmentAccessor());
                sec.setBeanResolver(new BeanFactoryResolver(beanExpressionContext.getBeanFactory()));
                sec.setTypeLocator(new StandardTypeLocator(beanExpressionContext.getBeanFactory().getBeanClassLoader()));
                sec.setTypeConverter(new StandardTypeConverter(() -> {
                    ConversionService cs = beanExpressionContext.getBeanFactory().getConversionService();
                    return (cs != null ? cs : DefaultConversionService.getSharedInstance());
                }));
                this.evaluationCache.put(beanExpressionContext, sec);
            }
            return expr.getValue(sec);
        } catch (Throwable ex) {
            throw new BeanExpressionException("Expression parsing failed", ex);
        }
    }

    private final ParserContext beanExpressionParserContext = new ParserContext() {
        @Override
        public boolean isTemplate() {
            return true;
        }

        @Override
        public String getExpressionPrefix() {
            return "#{";
        }

        @Override
        public String getExpressionSuffix() {
            return "}";
        }
    };
}

使用示例

CustomSpringBeanExpressionEvaluator.evaluate("#{bean.fieldName}")

CustomSpringBeanExpressionEvaluator.evaluate("#{bean.methodName}")

相关推荐
SunnyDays10112 分钟前
Java 如何为 PDF 添加、修改和删除书签
java·pdf
铃木之影34 分钟前
Java 版本 RAG 示例(Spring AI + Milvus)
java·人工智能·spring
C++、Java和Python的菜鸟40 分钟前
第14章 项目部署(Linux)
java
吴懿不在 不负信仰1 小时前
从jQuery谈库与框架的设计之优劣
前端·javascript·jquery
灵析表格1 小时前
灵析表格手机号处理函数深度分析报告
前端·网络·json·wps·灵析表格·excel公式盒子
智海深蓝1 小时前
智慧渔业海上养殖数字孪生实践方向与难点拆解分析
java·前端·网络
2601_955760071 小时前
Claude API 多人协作中的版本管理方法
java·ai编程
丁引1 小时前
《数据清洗的艺术:如何用20行核心逻辑优雅地删除无标签图片》
前端·数据库·python
梦想的旅途21 小时前
企业微信API二次开发:外部群模块功能清单与全场景对接
java·python·企业微信
Bigger2 小时前
Han:一个让 AI Agent 也能做出高级中国风页面的 CSS 设计系统
前端·ai编程·设计