在Payara上部署.war之后,我正在使用以下类进行一些初始化。我可以看到init()方法实际上在应用程序启动期间被调用了两次。
package mypackage;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import lombok.extern.log4j.Log4j2;
@Log4j2
@ApplicationScoped
public class StartupService {
@Inject LogConfig logConfig;
void init(@Observes @Initialized(ApplicationScoped.class) Object init) {
log.debug("### STARTUP SERVICE CALLED ###");
logConfig.startup();
}
}
有人可以向我解释为什么这两次被召唤以及我如何避免它?
我的意思是,我当然可以实现一个静态布尔标志来识别我之前已经调用过一次,但是我更愿意修复根本原因并且只从头开始调用一次。
答案 0 :(得分:1)
好的,我会尝试对此进行总结,但可能并非如此,我可以尝试深入挖掘。但这是我认为正在进行的......
您可以获得两次事件,每次都有不同的有效负载。 这可能有多种原因,但最有可能的一个原因是Paraya在整合方面存在微小缺陷。 Weld建议集成商通过SPI定义其运行环境。如果他们不这样做,Weld可以处理它,但需要做一些假设和猜测,以满足规范要求。
在这种情况下,我怀疑Paraya错误地定义Environment并且Weld不确定要触发哪些事件 - 对于Web模块,需要使用ServletContext
有效负载触发事件,而其余部分模块具有普通Object
作为有效载荷。
可悲的是,除了抢先获取有关环境的信息之外,没有简单的方法可以防止这两个事件被解雇。原因是Weld需要在Web模块有任何挂钩活动之前很久就决定Object
有效负载事件。
您案例中的解决方案可能是将Object
指定为更具体的类型 - 因此只能观察到一个事件。根据您的示例,我假设ServletContext
有效负载将是您要查找的有效负载。