2017-10-12 248 views
0

我的.war部署在Payara后,我正在使用以下类进行一些初始化。我可以看到init()方法在应用程序启动过程中实际被调用了两次。为什么我的CDI启动类调用两次?

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(); 
    } 
} 

可为什么这个被称为两次我有人解释和我怎么能避免呢?

我的意思是,我当然可以实现静态布尔标志认识到,我已经过一次叫,但我宁愿解决的根本原因,只有得到所谓从一开始就一次。

+1

为什么不使用'@ PostConstruct'? – juvenislux

+0

这可能与不同的事件有效载荷(CDI规范,6.7.3应用程序上下文生命周期)有关 - 可以检查有效载荷是什么样的?它是'Object'还是'ServletContext'(你可以使用'instanceof')?我的赌注是每一次。如果是这样的话,我可以就我所知进一步制定:) – Siliarus

+0

@juvenislux'@ ApplicationScoped'和'@ PostConstruct'不会导致启动过程中即时加载的类。你仍然需要“某人”来@ @注入@ @ PostConstruct这个类来执行 –

回答

1

好吧,我会尝试总结这件事,它可能不完全的情况下,我可以尝试深入挖掘。但这里是用不同的有效载荷,每次我想是怎么回事...

你获得的事件两次。 这可能有多种原因,但最有可能的一个原因是Paraya在集成方面存在一个小小的缺陷。 Weld建议集成商通过SPI来定义其运行环境。如果他们不这样做,Weld可以处理它,但需要做一些假设和猜测以满足规范要求。

在这种情况下,我怀疑Paraya错误地定义Environment和焊接是不知道火的事件 - 对于Web模块,有一个与ServletContext有效载荷火灾事件的要求,而模块的其余部分具有普通Object作为有效载荷。

可悲的是,有没有简单的方法,以防止被解雇,除了抢先有关于环境信息两个事件。原因是在Web模块有任何挂钩活动之前,Weld需要确定有关负载事件Object

您的情况的解决方案可能会将Object指定为更具体的类型 - 因此只能观察到一个事件。根据你的样品,我假设ServletContext有效载荷将是你正在寻找的。

+0

谢谢你的解释!我会试试看 –

相关问题