for f:actionlistener the spec defines:
'If binding is set, create a ValueExpression by invoking
Application.createValueExpression() with binding as the expression argument,
and Object.class as the expectedType argument. Use the ValueExpression to obtain
a reference to the ActionListener instance. If there is no exception thrown, and
ValueExpression.getValue() returned a non-null object that implements
javax.faces.event.ActionListener, register it by calling addActionListener().
If there was an exception thrown, rethrow the exception as a JspException.'
According to this the instance returned by evaluation of the binding-expression
would have to be used. It doesn't mention that it's legal to use a lazy-loading
wrapper for optimization (as it is used in the RI).
adding the instance of ActionListener that is returned from evaluation of the
binding-expression to the ActionSource implementing UIComponent would result in
this very instance being used on all subsequent postback-requests. In case the
binding-expression references e.g. a request-scoped managed bean the listener
would reference the outdated instance on postback because the binding-expression
would not be reevaluated again.
Since this is undesirable behaviour the spec should either specify that the
binding-expression has to be reevaluated on every request, or that the Listener
being referenced must not be an object in request-scope.
definitions of f:phaselistener and f:valuechangelistener face the same issue.
(The RI makes use of a ActionListener-wrapper that evaluates the binding lazy.
In conjunction with client-side statesaving it would reevaluate the binding
expression on every request. With serverside-statesaving it would cache and
return the same instance later, which is inconsistend - I've filed issue # 656
(https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=656) against the RI
to trak this.)