Conforming to documentation, "if
the class to which @ListenerFor annotation is attached implements SystemEventListener and does not implement ComponentSystemEventListener, "target" is the Application instance".
Based on this affirmation, it is possible to believe that the below
example will work and will register the TomComponent as a listener for all emitters
capable to emit the PostAddToViewEvent
event (not just instances of TomComponent):
@FacesComponent(value
= TomComponent.COMPONENT_TYPE, createTag = true)
@ListenerFor(systemEventClass =
PostAddToViewEvent.class)
public class
TomComponent extends UIComponentBase implements SystemEventListener {
public static final String COMPONENT_FAMILY =
"jsf.component";
public static final String COMPONENT_TYPE = "jsf.component.TomComponent";
@Override
public
void processEvent(SystemEvent event) throws AbortProcessingException {
System.out.println("EVENT EMITTED:
" + event);
}
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
@Override
public
boolean isListenerForSource(Object source) {
System.out.println("EVENT SOURCE: "
+ source);
return true;
}
...
}
But, remember that an custom component implements the ComponentSystemEventListener
interface by inheritance from UIComponent!
So, the output of the above case will be:
EVENT SOURCE:
jsf.component.TomComponent
And the processEvent(SystemEvent
event) is not called! Since ComponentSystemEventListener is inherited (so
implemented), and we have the @ListenerFor,
the TomComponent
will be registered as the listener for PostAddToViewEvent event emitted only by instances of TomComponent. But, as
you notice from the above output, the flow passes through the isListenerForSource(Object
source), which means that, in this particular case, we need to return true;, or return source instanceof
TomComponent;, otherwise we will block the call of the processEvent(ComponentSystemEventListener
event) method.
So, combining @ListenerFor
with SystemEventListener
and UIComponents
is not a good thing, only if you really know what you are doing.
Well, the things changes in case of combining the @ListenerFor with SystemEventListener and Renderer. Since Renderer doesn't implement the ComponentSystemEventListener, we are in
the case from the documentation quoted above. Now, the reasoning is going
further and "If "target"
is the Application instance, inspect the value of
the sourceClass() annotation attribute value. If the value is Void.class, call Application.subscribeToEvent(Class,
SystemEventListener), passing the value of systemEventClass()
as the first argument and the instance of the class to which this annotation is
attached (which must implement SystemEventListener)
as the second argument".
Niciun comentariu :
Trimiteți un comentariu