【发布时间】:2017-10-12 08:15:02
【问题描述】:
在我的 .war 部署到 Payara 后,我正在使用以下类进行一些初始化。而且我可以看到,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();
}
}
有人可以向我解释为什么这会被调用两次以及如何避免它?
我的意思是,我当然可以实现一个静态布尔标志来识别我之前已经被调用过一次,但我更愿意修复根本原因并且只从一开始就被调用一次。
【问题讨论】:
-
为什么不使用
@PostConstruct? -
这可能与不同的事件负载(CDI 规范,6.7.3 应用程序上下文生命周期)有关 - 你能检查一下负载是什么样的吗?是
Object还是ServletContext(可以使用instanceof)?我敢打赌,它每个一次。如果是这样,我可以进一步详细说明:) -
@juvenislux 据我所知
@ApplicationScoped和@PostConstruct不会导致类在启动期间被急切地加载。您仍然需要“某人”到@Inject某个地方的班级才能执行@PostConstruct -
@Siliarus 你猜对了,有效载荷不同。在第一次调用时,它是一个 ContextEvent 对象,其中包含“应用程序上下文已初始化”的字符串消息,而在第二次调用时,它是 ApplicationContextFacade 类型的对象。是时候让你进一步阐述了:)
标签: jakarta-ee cdi startup payara