Java CDI@ApplicationScoped

Java CDI@ApplicationScoped,java,cdi,jboss-weld,Java,Cdi,Jboss Weld,我有一个带注释的对象 @ApplicationScoped public class DbGraphConnectionLocator implements ServerStopTask { ... } @ApplicationScoped public class DbGraphConnectionLocator implements ServerStopTask { ....} 此对象用于创建嵌入式数据库 我试图在重新部署应用程序时创建一个钩子来关闭数据库 所以我构建了这个类 @WebL

我有一个带注释的对象

@ApplicationScoped
public class DbGraphConnectionLocator implements ServerStopTask {
...
}
@ApplicationScoped
public class DbGraphConnectionLocator implements ServerStopTask { ....}
此对象用于创建嵌入式数据库

我试图在重新部署应用程序时创建一个钩子来关闭数据库

所以我构建了这个类

@WebListener
public class UndeployHook implements ServletContextListener{
@Inject
DbGraphConnectionLocator dbGraphConnectionLocator;


@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {

}

@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
    try {
        dbGraphConnectionLocator.executeStopTask();
        } catch (Exception e) {
        e.printStackTrace();
        }
    }
}
实际上调用了contextDestoyed方法,但中使用的对象不是启动时创建的DbGraphConnectionLocator的原始对象,这给我带来了一些麻烦

在我看来,与注释

@ApplicationScoped
public class DbGraphConnectionLocator implements ServerStopTask {
...
}
@ApplicationScoped
public class DbGraphConnectionLocator implements ServerStopTask { ....}
DbGraphConnectionLocator的实例在应用程序级别必须是唯一的,因此当我将其与

@Inject
DbGraphConnectionLocator dbGraphConnectionLocator;
我必须找到我的应用程序在启动时创建的同一个实例,但这不是真的,而是创建了另一个实例

无论如何,我决定添加

@PreDestroy
public  void shutdownDB(){
    graphDb.shutdown();
}
到DbGraphConnectionLocator。 关于信息,我看到这个方法是在contextDestroyed方法之后调用的,这意味着当contextDestroyed被调用时,原始实例仍然存在,所以我错过了一些东西


有任何提示吗?

如果嵌入式数据库应在应用程序启动时创建,并在应用程序停止时关闭,只需执行以下操作:

这应该可以做到。 或者,您也可以使用CDI生产者创建应用程序范围的db连接。然后可以使用disposer方法断开与数据库的连接


在您的情况下,该行为是正确的,因为当调用web侦听器时,应用程序必须仍然处于活动状态。因此,当应用程序范围的bean被销毁时,随后将调用带有@PreDestroy的shutdownDB方法。由于您在侦听器中引用了它,因此它必须一直保持活动状态,直到侦听器被销毁。

感谢您的响应,即使在我的情况下,PreDestroy解决了这个问题。我不明白为什么在注释应用程序的作用域公共类DbGraphConnectionLocator实现ServerStopTask{…}时会调用contextDestoyed,但中使用的对象不是启动时为我创建的DbGraphConnectionLocator的原始对象。似乎web服务器在全局bean管理器尚未启动时注入了您的bean,所以它必须创建另一个bean实例