I have added a PhaseListener
to faces-config.xml
:
<lifecycle>
<phase-listener>com.project.NotificationListener</phase-listener>
</lifecycle>
The class seems to be otherwise correct as it is pretty simple.
public class NotificationListener implements PhaseListener {
@Inject
private MyCDIStuff stuff;
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
@Override
public void beforePhase(PhaseEvent event) {
this.stuff.doStuff();
}
}
The 'beforePhase' method gets called correctly, however the MyCDIStuff object is null. I tried using annotation @Singleton
for the class which most likely was incorrect, and it didn't make the injection work either.
Is there a way to inject CDI managed beans in the PhaseListener
?
Before JSF 2.2,
PhaseListener
s are not registered as CDI injection targets. Using@Inject
(and@EJB
) has effectively no effect inPhaseListener
s. You'd need to manually grab the CDI managed beans by programmatically evaluating an EL expression referencing the@Named
's (implicit) name, or as last resort via JNDI andBeanManager
which is quite clumsy.So, if you can't upgrade to JSF 2.2 (which should be compatible with any JSF 2.0/2.1 and Servlet 3.0 compatible web application), then your best bet is programmatically evaluating an EL expression referencing the
@Named
name. Assuming that you've athen this should do:
If you can't go JSF 2.2 your best bet is to use Deltaspike Core.
It offers
MyCDIStuff myCDIStuff = BeanProvider.getContextualReference(MyCDIStuff.class, false);
Deltaspike is how you should get stuff rather then inventing that yourself. For example if you must have the BeanManager (for example to fire an event) then Deltaspike core also offers
BeanManagerProvider
.http://deltaspike.apache.org/core.html