为什么 @ApplicationScoped bean 在我的 CDI 扩展的 BeforeShutdown 阶段有一个新实例?

Ale*_*ler 2 java cdi weld

我想在关闭 CDI 应用程序时对 bean 进行一些清理。例如,我想关闭一个IO连接。当然,这里的bean被标记为@ApplicationScoped。

为了管理这个问题,我编写了一个扩展并观察 BeforeShutdown 事件,然后选择我的 bean 来调用清理方法:

public void beforeShutdown(@Observes BeforeShutdown beforeShutdown) {
    SomeBean obj = CDI.current().select(SomeBean.class).get();
    obj.cleanup();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我可以在此方法中访问新实例。不是我在整个应用程序中得到的实例。

如果您想查看此实例问题,我在 github 上创建了一个存储库来展示它: https: //github.com/hasalex/cdi-extension-demo

所以我有两个问题:

  • 为什么我会得到一个新实例?
  • 还有其他方法可以在应用程序结束时清理我的 bean 吗?(在 SE 和 WildFly 环境中)

小智 5

看这里:http ://docs.jboss.org/cdi/spec/1.1.EDR1/html/spi.html#provider

11.5.4。关闭前事件

容器在完成处理请求并销毁所有上下文后必须触发最终事件。

也许您想使用@PreDestroy:http://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html

使用 javax.annotation.PreDestroy 注释来注释方法的声明。

CDI 在开始销毁 bean 之前调用此方法。