SpEL 模板的存在作用
手动编写模板
String template = "${user.level} >= 5";
然后手动写代码替换 ${user.level}
为具体值:
String filled = template.replace("${user.level}", String.valueOf(user.getLevel()));
再执行逻辑判断:
if (Integer.parseInt(filled.split(" >= ")[0]) >= 5) {
// 允许访问
}
这当然是可以实现“动态效果”的,而且手动拼接模板在逻辑简单、性能要求高的场景下也非常常见。
🔍 SpEL 与“模板手动替换”对比分析
对比项 | 手写模板替换 | SpEL |
---|---|---|
✅ 灵活性 | 一般,必须写具体规则匹配 | 强,支持复杂逻辑、对象访问、函数等 |
✅ 动态表达式支持 | 弱,只能靠自己写解析器 | 强,支持运算、调用方法、三元、正则等 |
✅ 类型推导 | 需手动判断类型 | 自动推导,如 #user.level >= 5 |
✅ 嵌套对象访问 | 要手动实现解析、映射 | 支持 #user.profile.address.city |
✅ 安全控制 | 安全,但功能非常有限 | 有注入风险,配合变量防护后安全 |
✅ 学习曲线 | 简单直白 | 需要理解表达式语法和上下文机制 |
✅ 适用场景 | 规则简单、性能敏感 | 规则复杂、需动态修改或非工程师配置 |
✅ 举个例子:权限规则动态化
手动模板方式:
String template = "${user.level} >= 10";
String expr = template.replace("${user.level}", String.valueOf(user.getLevel()));
boolean result = Integer.parseInt(expr.split(" >= ")[0]) >= 10;
只能支持这种简单条件;若表达式为:
"${user.vip} && (${user.level} >= 10 || ${user.role} == 'admin')"
那就变得很难解析,除非你自己造一个完整的表达式解析器。
SpEL 方式:
String expr = "#user.vip and (#user.level >= 10 or #user.role == 'admin')";
StandardEvaluationContext ctx = new StandardEvaluationContext();
ctx.setVariable("user", user);
Boolean result = parser.parseExpression(expr).getValue(ctx, Boolean.class);
无须关心解析、替换、类型转换,全自动完成,表达力也更强。
✅ 总结建议
场景 | 推荐方式 |
---|---|
条件简单、表达式少、性能敏感 | 手动模板拼接 |
条件复杂、表达式频繁变化、由配置/数据库控制 | SpEL(配合变量注入防护) |
要求前后端/运维人员可以配置规则 | SpEL 更优(非编程人员可直接写规则) |
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容