【发布时间】:2020-06-16 20:15:01
【问题描述】:
我有一个 @ApplicationScoped bean,我想在应用程序启动时对其进行实例化(参见下面的示例代码)。我已经注册了 servlet 上下文初始化事件,但从未调用过 init 方法。 FactoryLocator 包含在我的战争的 WEB-INF/lib 目录中的一个 jar 中。同样的代码在 Wildfly 9 上运行,但在升级到 Wildfly 16 后不再运行。
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.servlet.ServletContext;
@ApplicationScoped
public class FactoryLocator {
public FactoryLocator() {
System.out.println("In the constructor.........................");
}
private void init(@Observes @Initialized(ApplicationScoped.class) ServletContext sc) {
System.out.println("Invoking the event observer method..................");
}
}
我发现的一个解决方法是将我的战争的 WEB-INF/lib/ 目录中的 jar 的内容提取到我的战争的 WEB-INF/classes 目录中。当我这样做时,我的 FactorLocator bean 被成功实例化。我宁愿不必这样做。
通过war的部署调试后,我注意到ServletContext在war的lib目录中的所有bean都被处理之前被初始化(org.jboss.weld.bootstrap.BeanDeploymentModules:processBeanDeployments)。在处理完所有 bean 之前,war 的模块并不知道所有的观察者。但是,ServletContextEvent 在所有观察者都知道之前被触发。
是否应该在所有观察者都知道之前创建 ServletContext ?我已经调试了一个 Wildfly QuickStart 应用程序,并且在处理完所有 bean 部署并且成功执行下面的代码之前,不会创建 ServletContext。发生这种情况的顺序是否应该得到保证?
【问题讨论】:
-
发现了 bean,但问题似乎是由于在处理 bean 和发现观察者方法之前发出了 ServletContextEvent。