为什么我的 CDI 启动 class 被调用了两次?
Why is my CDI startup class called twice?
在 .war 部署到 Payara 后,我正在使用以下 class 进行一些初始化。而且我可以看到 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();
}
}
有人可以向我解释为什么这会被调用两次吗?我该如何避免?
我的意思是,我当然可以实现一个静态布尔标志来识别我之前已经被调用过一次,但我更愿意修复根本原因并且从一开始只被调用一次。
好吧,我会试着总结一下,事实可能并非如此,我可以尝试更深入地挖掘。但这是我认为正在发生的事情......
您获得了两次事件,每次都有不同的负载。
这可能有多种原因,但最有可能的原因是 Paraya 在集成方面存在微小缺陷。 Weld 建议集成商通过 SPI 定义其运行的环境。如果他们不这样做,Weld 可以处理它,但需要做一些假设和猜测以满足规范要求。
在这种情况下,我怀疑 Paraya 错误地定义了 Environment 并且 Weld 不确定要触发哪些事件 - 对于 Web 模块,需要使用 ServletContext
负载触发事件,而模块的其余部分有普通的 Object
作为有效载荷。
遗憾的是,除了抢先获得有关环境的信息外,没有简单的方法可以防止这两个事件被触发。原因是 Weld 需要在 Web 模块的任何挂钩处于活动状态之前很久就决定 Object
有效载荷事件。
您的解决方案可能是将 Object
指定为更具体的类型 - 这样只会观察到一个事件。根据您的示例,我假设 ServletContext
有效载荷将是您正在寻找的那个。
在 .war 部署到 Payara 后,我正在使用以下 class 进行一些初始化。而且我可以看到 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();
}
}
有人可以向我解释为什么这会被调用两次吗?我该如何避免?
我的意思是,我当然可以实现一个静态布尔标志来识别我之前已经被调用过一次,但我更愿意修复根本原因并且从一开始只被调用一次。
好吧,我会试着总结一下,事实可能并非如此,我可以尝试更深入地挖掘。但这是我认为正在发生的事情......
您获得了两次事件,每次都有不同的负载。 这可能有多种原因,但最有可能的原因是 Paraya 在集成方面存在微小缺陷。 Weld 建议集成商通过 SPI 定义其运行的环境。如果他们不这样做,Weld 可以处理它,但需要做一些假设和猜测以满足规范要求。
在这种情况下,我怀疑 Paraya 错误地定义了 Environment 并且 Weld 不确定要触发哪些事件 - 对于 Web 模块,需要使用 ServletContext
负载触发事件,而模块的其余部分有普通的 Object
作为有效载荷。
遗憾的是,除了抢先获得有关环境的信息外,没有简单的方法可以防止这两个事件被触发。原因是 Weld 需要在 Web 模块的任何挂钩处于活动状态之前很久就决定 Object
有效载荷事件。
您的解决方案可能是将 Object
指定为更具体的类型 - 这样只会观察到一个事件。根据您的示例,我假设 ServletContext
有效载荷将是您正在寻找的那个。