使用OmniFaces 3.1时beanManager.fireEvent无法触发事件
解决BeanManager.fireEvent无法触发事件的问题
嘿,我看你已经确认BeanManager成功注入了,但fireEvent就是没起作用,结合你使用OmniFaces 3.1、WildFly 12 EAR环境的情况,我整理了几个大概率能解决问题的排查方向:
1. 先检查事件观察者的配置是否合规
首先得确认你的事件观察者方法符合CDI的要求:
- 观察者方法必须在CDI管理的Bean里——比如无状态会话Bean、
@RequestScoped/@ApplicationScoped这类CDI Bean,不能是普通的非托管类 - 方法参数一定要加
@Observes注解,比如正确写法应该是:
public void handleFoodsChange(@Observes FoodsCosmeticsMedicines event) { // 这里写你的事件处理逻辑 }
- 如果用了自定义限定符,触发事件时必须带上对应的限定符实例,比如:
beanManager.fireEvent(foodsCosmeticsMedicines, MyCustomQualifier.Literal.INSTANCE);
2. 确认EAR包的CDI启用配置没毛病
WildFly的EAR环境有时候需要显式启用CDI:
- 去你的EAR的
META-INF目录下看看有没有beans.xml文件,哪怕是空的也行(CDI 1.1+支持隐式归档,但EAR场景下偶尔需要显式声明) beans.xml的版本要匹配WildFly 12的CDI 2.0版本,配置可以参考这个:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="all"> </beans>
3. 检查事件类的可见性
事件类FoodsCosmeticsMedicines得满足两个条件:
- 必须是public类,不能是包私有或者protected
- 如果你的EAR包含多个模块(比如EJB模块和Web模块),这个事件类得放在所有模块都能访问到的地方——比如EAR的
lib目录下的共享Jar,或者在各个模块中正确导入依赖
4. 试试用OmniFaces的Events工具类替代原生BeanManager
虽然你现在用的是原生BeanManager.fireEvent,但OmniFaces提供了更简洁的Events工具类,说不定能绕过一些环境兼容问题:
import org.omnifaces.cdi.Events; @Inject private Events events; // 用这个触发事件试试 events.fire(foodsCosmeticsMedicines);
记得确保OmniFaces的Jar包放在EAR的lib目录下,或者在需要的模块中正确引入依赖。
5. 打开WildFly的CDI调试日志找线索
如果上面的方法都不行,建议开启WildFly的CDI调试日志,看看事件触发时有没有隐藏的错误:
- 编辑WildFly的
standalone.xml,添加这段日志配置:
<logger category="javax.enterprise"> <level name="DEBUG"/> </logger>
重启服务器后,查看日志里有没有关于CDI事件注册、触发的警告或错误信息——比如观察者没被正确注册的提示,这能帮你快速定位问题。
6. 考虑事务上下文的影响
你的方法是在无状态会话Bean里,默认会处于事务上下文中:
- CDI事件默认是同步触发的,如果事务回滚,有些观察者可能不会执行(取决于观察者方法的事务注解)
- 可以给观察者方法明确指定事务阶段,比如:
public void handleFoodsChange(@Observes(during = TransactionPhase.AFTER_SUCCESS) FoodsCosmeticsMedicines event) { // 事务成功后再触发这个观察者 }
内容的提问来源于stack exchange,提问作者NOTiFY
相关产品推荐
相关产品推荐

