You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by "Pfau, Oliver" <ol...@siemens.com> on 2006/11/16 17:13:07 UTC

PhaseListener behaviour

Hi,
 
I have a phase listener defined in a backing bean constructor:
 
... 
LifecycleFactory lifecycleFactory =
(LifecycleFactory)
FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle =
lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
lifecycle.addPhaseListener(new PhaseListener()
{
	public void beforePhase(PhaseEvent event)
 	{
		if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
 		{
			// invoke a method of the backing bean from this
anonymous class
		}
	}
 	
	public void afterPhase(PhaseEvent event)
 	{
		if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION)
	 	{
  		}
	}

 

	public PhaseId getPhaseId()
	{

		return PhaseId.ANY_PHASE;

	}
});
...


How does this phase listener work ? I thought the call of the backing
bean class will only affect the backing bean in the current session. But
after debug it seems that all backing bean of all users are affected.
Does someone know the behaviour exactly ?

Thanks,
Oliver


Re: PhaseListener behaviour

Posted by Simon Kitching <si...@rhe.co.nz>.
Gerald Müllan wrote:
> you have to make sure every time to make a phaseListener thread safe.
> Means it is shared by all user among the incoming requests.
>
> A PL for only one user in only one session is not the way it works..

Yep. If you want to get "per-page" callbacks to a backing bean (rather 
than callbacks triggered by components) then a PhaseListener is *not* 
the right solution (at least not without a lot of extra clever stuff). 
As Gerald notes, PhaseListener classes are application-wide (shared by 
all users); it can use FacesContext.getCurrentInstance to determine the 
right context for the current user, but cannot easily determine what 
backing bean methods to then invoke.

The Apache Shale library has one solution, the "view controller" module. 
It does use a PhaseListener, but also hooks the ViewHandler and various 
other bits to provide the phase listener with enough info to figure out 
what beans to invoke. It's still a pretty limited solution in many ways 
though.

The project I'm currently working on initially used a 
PhaseListener-based approach for "per-page" callbacks, where the 
PhaseListener used a list of managed beans stored in a session-scope 
attribute to determine what callbacks to make This turned out to be 
fundamentally flawed. I've recently replaced this with another approach: 
a custom component that has "onRender" and "onPostback" attributes that 
are method bindings. On call to its processDecodes method it invokes the 
onPostback method binding (if any), and on encodeBegin it invokes the 
onRender method binding (if any). For any page where an associated 
backing bean needs page-related callbacks, this tag can just be added to 
the page. It's pretty simple and very effective so far. It handles pages 
that are composed of separate fragments using includes much more 
elegantly than the shale approach for example. It also keeps 
page-relevant configuration in the page rather than in the faces config 
file. I think a component like this could be a useful addition to tomahawk.

Regards,

Simon

Re: PhaseListener behaviour

Posted by Gerald Müllan <bi...@gmail.com>.
Hi,

you have to make sure every time to make a phaseListener thread safe.
Means it is shared by all user among the incoming requests.

A PL for only one user in only one session is not the way it works..

cheers,

Gerald

On 11/16/06, Pfau, Oliver <ol...@siemens.com> wrote:
> Hi,
>
> I have a phase listener defined in a backing bean constructor:
>
> ...
> LifecycleFactory lifecycleFactory =
> (LifecycleFactory)
> FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
> Lifecycle lifecycle =
> lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
> lifecycle.addPhaseListener(new PhaseListener()
> {
>         public void beforePhase(PhaseEvent event)
>         {
>                 if (event.getPhaseId() == PhaseId.RENDER_RESPONSE)
>                 {
>                         // invoke a method of the backing bean from this
> anonymous class
>                 }
>         }
>
>         public void afterPhase(PhaseEvent event)
>         {
>                 if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION)
>                 {
>                 }
>         }
>
>
>
>         public PhaseId getPhaseId()
>         {
>
>                 return PhaseId.ANY_PHASE;
>
>         }
> });
> ...
>
>
> How does this phase listener work ? I thought the call of the backing
> bean class will only affect the backing bean in the current session. But
> after debug it seems that all backing bean of all users are affected.
> Does someone know the behaviour exactly ?
>
> Thanks,
> Oliver
>
>


-- 
http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces