如何在EL Processor中定义带命名空间的变量?
实现EL Processor支持带命名空间的变量
要让EL Processor识别${sys:com.foo.bar}这类带命名空间的变量并解析为System.getProperty的值,你需要自定义ELResolver来实现——defineFunction仅用于注册EL函数,和变量解析逻辑无关。具体步骤如下:
1. 自定义ELResolver类
这个Resolver会拦截指定前缀(比如sys)的变量,将前缀后的部分作为系统属性键获取对应值:
import javax.el.ELContext; import javax.el.ELResolver; import java.beans.FeatureDescriptor; import java.util.Iterator; public class NamespaceVariableResolver extends ELResolver { // 目标命名空间前缀 private static final String SYS_PREFIX = "sys"; @Override public Object getValue(ELContext context, Object base, Object property) { // 处理顶级变量(base为null时对应${prefix:key}格式) if (base == null && property instanceof String) { String variable = (String) property; int colonIndex = variable.indexOf(':'); if (colonIndex != -1) { String prefix = variable.substring(0, colonIndex); String propKey = variable.substring(colonIndex + 1); if (SYS_PREFIX.equals(prefix)) { // 标记该变量已被处理,避免后续Resolver重复处理 context.setPropertyResolved(true); // 返回系统属性值,不存在则返回null return System.getProperty(propKey); } } } // 非目标命名空间变量,交给后续Resolver处理 return null; } // 以下为必须实现的抽象方法,按默认逻辑处理即可 @Override public Class<?> getType(ELContext context, Object base, Object property) { return Object.class; } @Override public void setValue(ELContext context, Object base, Object property, Object value) { // 仅处理变量读取,不支持写入,留空即可 } @Override public boolean isReadOnly(ELContext context, Object base, Object property) { return true; } @Override public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) { return null; } @Override public Class<?> getCommonPropertyType(ELContext context, Object base) { return String.class; } }
2. 注册自定义Resolver到ELProcessor
创建ELProcessor实例后,将自定义Resolver添加到它的解析器链中:
ELProcessor elProcessor = new ELProcessor(); // 把自定义Resolver放在链的最前面,确保优先处理命名空间变量 elProcessor.getELManager().addELResolver(new NamespaceVariableResolver()); // 测试示例 String userDir = elProcessor.eval("${sys:user.dir}").toString(); System.out.println(userDir); // 输出当前用户工作目录
补充说明
- 若需支持多个命名空间,可在
NamespaceVariableResolver中扩展前缀判断逻辑,添加对应处理分支即可。 - ELResolver的调用顺序遵循添加顺序,将自定义Resolver放在前面能确保它优先拦截目标变量,避免被默认Resolver提前处理。
内容的提问来源于stack exchange,提问作者user5182503
相关产品推荐
相关产品推荐

