毫无疑问,您已经在与Maven/Spring/Log4j相关的XML配置文件中看到了这一点.不幸的是,他们没有利用雅加达解决这些问题.他们暗地里用Apache Commons Text StringSubstitutor
来做这个.而且,雅加达El从一开始就不支持这个syntax.它甚至在有机会命中任何定制的EL侦听器或EL解析器之前就已经死于语法错误.
对于Jakarta EL,最好的 Select 是将语法更改为${sys['com.foo.bar']}
,并添加一个定制ELResolver
,它将${sys}
识别为特殊类型的基数,然后通过System#getProperty()
解析其余部分.
以下是此类EL解析器的启动工作示例:
public class SystemPropertyELResolver extends ELResolver {
@Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return (base == this) ? String.class : null;
}
@Override
public Class<?> getType(ELContext context, Object base, Object property) {
if (base == null && "sys".equals(property)) {
context.setPropertyResolved(true);
return getClass();
}
else if (base == this && property != null) {
context.setPropertyResolved(true);
return getCommonPropertyType(context, base);
}
return null;
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
if (base == null && "sys".equals(property)) {
context.setPropertyResolved(true);
return this;
}
else if (base == this && property != null) {
context.setPropertyResolved(true);
return System.getProperty(property.toString());
}
return null;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object val) {
// NOOP.
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return true;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
}
要使其运行,请按如下方式进行注册:
elProcessor.getELManager().addELResolver(new SystemPropertyELResolver());
然而,在System#getProperty()
的specific种情况下,还有另一种更简单的"使用名称空间定义变量"的方法.因为System#getProperties()
已经返回了java.util.Map
的实例,所以可以使用内置jakarta.el.MapELResolver
来处理它,同时使用与${sys['com.foo.bar']}
相同的语法.
elProcessor.defineBean("sys", System.getProperties());
这只会给您提供进一步定制EL分辨率的机会.