我有一个带有注释的on Object
@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 { ....}
DbGraphConnectionLocator的实例在应用程序级别必须是唯一的,因此当我将其与
@Inject
DbGraphConnectionLocator dbGraphConnectionLocator;
我必须找到由我的应用程序启动时创建的同一实例,但这不是事实,已创建另一个实例。
无论如何我决定添加
@PreDestroy
public void shutdownDB(){
graphDb.shutdown();
}
到DbGraphConnectionLocator。
对于信息,我看到此方法在contextDestroyed方法之后被调用,这意味着当调用contextDestroyed时,原始实例仍然存在,所以我错过了一些东西。
有什么提示吗?
最佳答案
如果嵌入式数据库应在应用程序启动时创建,并在应用程序停止时关闭,则请执行以下操作:
@ApplicationScoped
@Startup
public class AnyNameForYourApplicationClass {
@PostConstruct
public void connectDB() {
// creates the db connection at startup
}
@PreDestoy
public void disconnectDB() {
// disconnects from the db
}
}
这应该做。
或者,您也可以使用CDI生产者来创建应用程序范围的db连接。然后,您可以使用处理程序方法从数据库断开连接。
在您的情况下,此行为是正确的,因为在调用Web侦听器时,该应用程序必须仍然处于活动状态。因此,在销毁应用程序作用域的bean之后,将使用@PreDestroy调用shutdownDB方法。并且由于您是在侦听器中引用它,因此它必须一直存在,直到侦听器被销毁为止。