表达式工厂(Expression Factory)
如果要使用EL
,就必须要有一个javax.el.ExpressionFactory
的实例。表达式工厂用于创建多种类型的表达式。JUEL
的表达式工厂实现类是de.odysseus.el.ExpressionFactoryImpl
,获得表达式工厂实例的最方便方法是:
javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
表达式工厂是线程安全的,允许创建数量不限的表达式。表达式工厂提供下面的操作:
提供类型强制转换(Type coercions)
创造树状值表达式(Tree value expressions)
创建对象值表达式(Object value expressions)
创建树状方法表达式(Tree method expressions)
表达式缓存
每一个工厂实例使用它自己的表达式缓存。缓存的表达式是一个很重要的特性,因为解析是一个相对昂贵的操作。一个表达式缓存映射表达式字符串到他们已经解析过的表达方式(树)。
JUEL
提供一个缓存接口,该接口允许应用使用他们自己的缓存机制。虽然,在绝大多数情形中,JUEL
的默认实现应该是足够好的。默认缓存使用下面两种映射:
主映射是用java.util.LinkedHashMap
实现的,如果缓存的上线达到,那么新的实体(entry)会被添加,并且用最近使用原则(LRU
)从主映射里移除旧的映射关系,并把旧的映射关系保存到二级映射表中。
二级映射表是用java.util.WeakHashMap
来实现的。实体保证生命期至少和他们字符串的强引用一样长。没有任何引用的时候对应的实体才可能被垃圾回收器回收。
默认的构造器使用的缓存容量是1000,你可以通过设置javax.el.cacheSize
属性来自定义缓存大小,比如5000:
java.util.Properties properties = new java.util.Properties();
properties.put("javax.el.cacheSize", "5000");
javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(properties);
使用自己的缓存机制可以参考“高级主题”一节。
类型转换
在计算表达式中,有几个点可能会进行类型转换。
算术或逻辑操作中进行的强制转换
值表达式强制转换成创建时期望的类型
字符方法表达式计算的文字会强制转换成创建时期望的类型
非字符方法表达式,最后一个属性强制转换到方法名(翻译不出来)
符合表达式在连接的时候强制转换所有字表达式为字符串
所有这些强制转换依照的都是同样的规则,规范中对这些强制转换规则有详细的描述。它支持字符串、字符、布尔、枚举、数字类型间的转换,而且从字符串转换到其他类型使用了JavaBeans
的属性编辑器来支持。客户端程序通过表达式工厂方法能够实现EL
的强制转换规则。
ExpressionFactoryImpl.coerceToType(Object, Class>)
上面那段代码返回的是Object
类型对象。JUEL
能被配置成用其他的强制转换规则,具体可以参考“高级主题”一段。
工厂配置
工厂可以通过属性文件配置。下面是不指定属性时,表达式工厂创建的机制,属性的查询如下:
JAVA_HOME/lib/el.properties
——如果存在javax.el.ExpressionFactory
属性,而且值是de.odysseus.el.ExpressionFactoryImpl
,那么JUEL
就作为默认的el启动;
System.getProperties()
——如果规则1没有符合,系统属性把javax.el.ExpressionFactory
的值设置为de.odysseus.el.ExpressionFactoryImpl
,这儿设置能覆盖1的设置;
el.properties
文件在类路径的任何地方——这里设置的属性能覆盖1和2成为默认值。
有了上面的那些,接下来下面的属性会读到:
javax.el.cacheSize
——表达式缓存的大小(默认是1000);
javax.el.methodInvocations
——如果设置成true
意味着允许方法调用。更多信息请参考“高级主题”一节;
javax.el.nullProperties
——如果设置成true
将解析null
属性。更多信息请参考“高级主题”一节;
javax.el.varArgs
——如果设置成true
则允许表达式里存在可变变量的函数/方法调用。
工厂类同样提了供构造器,可以让你准确的传递你的属性。如果你仅仅想要从JEE5
风格变成JEE6
风格,JUEL
提供枚举构造器作为profiles使用。