CDI @ApplicationScoped

时间:2014-10-22 14:41:40

标签: java cdi jboss-weld

我有一个带有注释的对象

@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时原始实例仍然存在,所以我想念一些....

任何提示?

1 个答案:

答案 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方法。因为你在你的监听器中引用它,它必须保持活着,直到监听器被销毁。