我有一个带有注释的对象
@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时原始实例仍然存在,所以我想念一些....
任何提示?
答案 0 :(得分:1)
如果嵌入式数据库应在应用程序启动时创建,并在应用程序停止时关闭,请执行以下操作:
@ApplicationScoped
@Startup
public class AnyNameForYourApplicationClass {
@PostConstruct
public void connectDB() {
// creates the db connection at startup
}
@PreDestoy
public void disconnectDB() {
// disconnects from the db
}
}
这应该这样做。 或者,您也可以使用CDI生成器来创建应用程序作用域数据库连接。然后,您可以使用处理程序方法断开与数据库的连接。
在您的情况下,行为是正确的,因为在调用Web侦听器时,应用程序必须仍处于活动状态。因此,在销毁应用程序作用域bean之后,将调用带有@PreDestroy的shutdownDB方法。因为你在你的监听器中引用它,它必须保持活着,直到监听器被销毁。