什么时候在CDI中发送@Initialized(ApplicationScoped.class)事件?

时间:2018-11-09 16:23:43

标签: java java-ee ejb cdi

我试图了解在扩展中可观察到的CDI容器引发的事件的上下文中@Initialized()事件的生命周期/流。

根据WELD 2 docs, the Container lifecycle events,是:

  
      
  • BeforeBeanDiscovery
  •   
  • ProcessAnnotatedType和ProcessSyntheticAnnotatedType
  •   
  • AfterTypeDiscovery
  •   
  • ProcessInjectionTarget和ProcessProducer
  •   
  • ProcessInjectionPoint
  •   
  • ProcessBeanAttributes
  •   
  • ProcessBean,ProcessManagedBean,ProcessSessionBean,ProcessProducerMethod和ProcessProducerField
  •   
  • ProcessObserverMethod
  •   
  • AfterBeanDiscovery
  •   
  • AfterDeploymentValidation
  •   
  • BeforeShutdown
  •   

我遇到的麻烦是,在此容器生命周期中@Initialized事件的触发位置。我怀疑它是在AfterDeploymentValidation之后完成的,但是我找不到任何文档来支持这一事实。另外,我似乎在CDI 1.1 spec中找不到任何指示@Initalized事件何时何地引发的内容。

例如,是否在所有发现的bean的所有@PostConstruct方法执行之前或之后引发该事件?是在初始化EJB @Startup之前还是之后引发事件?是否有任何文档清楚地列出了CDI中这些事件的顺序/顺序?

1 个答案:

答案 0 :(得分:1)

  

问题1:我很难找出的是在此容器生命周期中@Initialized事件的触发位置。我怀疑它是在AfterDeploymentValidation之后完成的,但是我找不到任何支持该事实的文档。

CDI 1.1 spec, section 11.5.4. AfterDeploymentValidation event中所述:

  

在确认没有部署问题之后,创建上下文或处理请求之前,容器必须触发事件。

A1 :因此,在任何范围内带有限定符@Initialized 的事件都会在之后 AfterDeploymentValidation触发事件。


  

第二季度:此外,我似乎在CDI 1.1规范中找不到任何指示@Initalized事件何时何地引发的内容。

A2:部分6.7. Context management for built-in scopes描述了每个内置范围的行为,并提供了有关自定义范围实现的建议:

  

在初始化自定义上下文时,鼓励便携式扩展使用限定符@Initialized(X.class)触发事件   ...
  初始化请求上下文时会触发带有限定符@Initialized(RequestScoped.class)的事件   ...等。


  

问题3:例如,该事件是在所有发现的bean的所有@PostConstruct方法执行之前还是之后引发的?

6.7. Context management for built-in scopes中所述:

  

请求范围是活动的:
    -...
    -在@PostConstruct回调任何bean的过程中。
  
    应用范围是活动的:
    -...
    -在@PostConstruct回调任何bean的过程中。
  ...等

A3 :要使作用域变为活动状态,需要先对其进行初始化。因此,将在任何bean的回调之前之前 @Initialized触发带有限定符@PostConstruct的事件,但仅针对必须在回调中处于活动状态的作用域。


  

问题4:是在初始化EJB @Startup之前还是之后引发事件?是否有任何文档清楚地列出了CDI中这些事件的顺序/顺序?

A4 :EJB由单独的规范JSR 345: Enterprise JavaBeans TM ,Version 3.2 EJB Core Contracts and Requirements覆盖。

根据4.8.1节中的Singleton Session Bean初始化:

  

默认情况下,容器负责确定何时初始化单例会话bean实例。但是,Bean Provider可以选择配置单例会话bean以进行初始化。如果Startup注释出现在单例会话Bean类上,或者如果已通过部署描述符将单例会话Bean指定为需要紧急初始化,则容器必须在应用程序启动序列期间初始化单例会话Bean实例。容器必须在任何外部客户端请求之前初始化所有此类启动时单例会话Bean(即,   来自应用程序外部的客户端请求)将传递到应用程序中的任何企业bean组件。
  ...
  在某些情况下,应用程序中的多个单例会话bean组件之间存在显式的初始化排序依赖性。 DependsOn批注用于表达这些依赖性。在一个单例会话bean必须在一个或多个其他单例会话bean之前初始化的情况下,使用DependsOn依赖项。容器确保在调用DependsOn方法之前已初始化与单身会话bean具有PostConstruct关系的所有单身会话bean。

因此,具有限定符@Initialized的事件也将在EJB bean的@PostConstruct回调之前被触发,但仅针对必须在回调中处于活动状态的作用域。