EL 解析可以通过ELResolver
实现进行定制。有两个 EL 解析器参与评估#{flash.keep.message}
。第一个,JSF-builtinFlashELResolver
在#{flash}
. 正如您在其源代码中看到的(行号与 Mojarra 2.2.12 匹配),
216 // and the property argument is "keep"...
217 if (property.toString().equals(FLASH_KEEP_VARIABLE_NAME))
218 {
219 elContext.setPropertyResolved(true);
220
221 // then this is a request to promote the value
222 // "property", which is assumed to have been previously
223 // stored in request scope via the "flash.now"
224 // expression, to flash scope.
225 result = base;
226 // Set a flag so the flash itself can look in the request
227 // and promote the value to the next request
228 FlashFactory ff = (FlashFactory)
229 FactoryFinder.getFactory(FactoryFinder.FLASH_FACTORY);
230 ff.getFlash(true);
231 ELFlash.setKeepFlag(facesContext);
232 }
计算表达式时FlashELResolver
将调用ELFlash.setKeepFlag(facesContext)
(第 231 行) 。#{flash.keep}
它还将属性设置为已解析(第 219 行),以便 EL 上下文可以使用下一个属性前进,并将base
(the #{flash}
) 设置为评估结果(第 225 行),因此有效地#{flash.keep}
返回了相同的#{flash}
对象。
然后,当message
要根据 的结果评估属性时#{flash.keep}
,本质上仍然是#{flash}
,但设置了“keep”标志,MapELResolver
则执行 EL-builtin。这是因为#{flash}
本质上是 a Map
,另请参见javadoc(强调我的)。
公共抽象类 Flash
扩展 Object
实现 Map<String,Object>
这将调用该Map#get()
方法,该方法在类中自定义Flash
如下(行号与 Mojarra 2.2.12 匹配):
384 public Object get(Object key) {
385 Object result = null;
386
387 FacesContext context = FacesContext.getCurrentInstance();
388 if (null != key) {
389 if (key.equals("keepMessages")) {
390 result = this.isKeepMessages();
391 } else if (key.equals("redirect")) {
392 result = this.isRedirect();
393 } else {
394 if (isKeepFlagSet(context)) {
395 result = getPhaseMapForReading().get(key);
396 keep(key.toString());
397 clearKeepFlag(context);
398 return result;
399 }
400
401 }
402
403 }
正如您在第 396 行看到的那样,它会keep(key)
在设置标志时调用,如FlashELResolver
.