【问题标题】:When is the @Initialized(ApplicationScoped.class) event sent in CDI?何时在 CDI 中发送 @Initialized(ApplicationScoped.class) 事件?
【发布时间】:2019-04-13 06:00:45
【问题描述】:

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

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

  • BeforeBeanDiscovery
  • ProcessAnnotatedType 和 ProcessSyntheticAnnotatedType
  • AfterTypeDiscovery
  • ProcessInjectionTarget 和 ProcessProducer
  • ProcessInjectionPoint
  • ProcessBeanAttributes
  • ProcessBean、ProcessManagedBean、ProcessSessionBean、ProcessProducerMethod 和 ProcessProducerField
  • ProcessObserverMethod
  • AfterBeanDiscovery
  • 部署后验证
  • 关机前

我很难找到在这个容器生命周期中@Initialized 事件会被触发的位置。我怀疑它是在部署验证后完成的,但我找不到任何文档来支持这一事实。此外,我似乎在CDI 1.1 spec 中找不到任何指示何时/何处引发@Initalized 事件的内容。

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

【问题讨论】:

    标签: java jakarta-ee ejb cdi


    【解决方案1】:

    Q1:我很难找到在这个容器生命周期中@Initialized 事件会被触发的位置。我怀疑它是在部署验证后完成的,但我找不到任何文档来支持这一事实。

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

    容器必须在验证不存在部署问题之后以及在创建上下文或处理请求之前触发事件。

    A1:因此,带有限定符@Initialized适用于任何范围的事件将在AfterDeploymentValidation事件之后触发。 p>


    Q2:此外,我似乎在 CDI 1.1 规范中找不到任何规定何时/何地抛出 @Initalized 事件的内容。

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

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


    Q3:比如,发现bean的@PostConstruct方法全部执行之前还是之后抛出的事件?

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

    请求范围处于活动状态:
    - ...
    - 在任何 bean 的 @PostConstruct 回调期间。

    应用范围有效:
    - ...
    - 在任何 bean 的 @PostConstruct 回调期间。
    ...等

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


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

    A4: EJB 包含在单独的规范 JSR 345: Enterprise JavaBeans TM ,Version 3.2 EJB Core Contracts and Requirements

    根据第 4.8.1 节 Singleton Session Bean Initialization 有:

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

    因此,带有限定符 @Initialized 的事件也将在 EJB bean 的 @PostConstruct 回调之前触发,但仅限于必须在回调中处于活动状态的范围。

    【讨论】:

      猜你喜欢
      • 2022-10-09
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      • 2021-12-30
      相关资源
      最近更新 更多