问题描述
我已将PhaseListener
添加到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();
}
}
正确调用了"beforePhase"方法,但是MyCDIStuff对象为null.我尝试对最有可能是不正确的类使用批注@Singleton
,它也无法使注入工作.
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.
是否可以在PhaseListener
中注入CDI管理的bean?
Is there a way to inject CDI managed beans in the PhaseListener
?
推荐答案
在JSF 2.2之前,PhaseListener
未注册为CDI注入目标.使用@Inject
(和@EJB
)在PhaseListener
中实际上无效.您需要通过以编程方式评估引用@Named
的(隐式)名称的EL表达式,或者通过JNDI和BeanManager
笨拙地作为最后手段,来手动获取CDI托管的bean.
Before JSF 2.2, PhaseListener
s are not registered as CDI injection targets. Using @Inject
(and @EJB
) has effectively no effect in PhaseListener
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 and BeanManager
which is quite clumsy.
因此,如果您不能升级到JSF 2.2(应该与任何与JSF 2.0/2.1和Servlet 3.0兼容的Web应用程序兼容),那么最好的选择就是以编程方式评估引用@Named
名称的EL表达式.假设您拥有
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 a
@Named("stuff")
public class MyCDIStuff {}
然后应该这样做:
FacesContext context = event.getFacesContext();
MyCDIStuff stuff = context.getApplication().evaluateExpressionGet(context, "#{stuff}", MyCDIStuff.class);
// ...
这篇关于如何在PhaseListener中@Inject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!