2

我正在使用 Servlet 3 (Tomcat 7) + Spring 3.1,并尝试使用 WebApplicationInitializer 加载我的 webapp。

在我见过的常见示例中,您有一个 Root ApplicationContext,加载了 ContextLoaderListener,还有一个 servlet ApplicationContext,加载了 DispatcherServlet。

(要清楚,我不是在谈论 web.xml,而是在 WebApplicationInitializer 内部以编程方式谈论)。

现在,我想要一个 ApplicationContexts 的层次结构,让我们说:

根 -> AppContext1 -> AppContext2 -> ServletAppContext

->表示父 -> 子关系。每个 AppContext 都可以访问自己的 bean 和其祖先的 bean。

例如:

  • Root 定义属性、DAO 和 TX。
  • AppContext1 定义了 JPA 和 Spring Data 存储库。
  • AppContext2 定义了 JMS 和 Spring 集成管道。
  • ServletAppContext 定义控制器和视图。

我的第一种方法是将Root ApplicationContext 添加到ContextLoaderListener,然后将其设置为AppContext1 的父级。将 AppContext1 设置为 AppContext2 的父级。将 AppContext2 设置为 ServletAppContext 的父级。最后将 ServletAppContext 与 DispatcherServlet 关联起来。

问题是,在关闭时,DispatcherServlet 会关闭 ServletAppContext,但它不会传播。AppContext1 和 AppContext2 永远不会关闭,它们的 bean 永远不会被释放。所以我猜我使用了错误的方法。

我尝试将 AppContext2 关联到 ContextLoaderListener 而不是 Root。在这种情况下,AppContext2 关闭,但 AppContext1 和 Root 保持打开状态。

我也不能有 3 个 ContextLoaderListener,我的每个 AppContexts(根、1、2)各有 1 个。

我的问题是,这种情况的正确方法是什么?我愿意接受建议。

4

2 回答 2

1

不关闭父上下文的默认行为是因为单个父上下文可以由多个子上下文共享。在这种情况下,只有在所有子上下文都关闭后才能关闭父上下文。

如果它是线性关系(即,每个上下文只有一个子级),那么您可以使用扩展的 ApplicationContext 实现,其 close 方法也调用父级 close。

如果它不是线性关系 - 那么您可以实现引用计数机制来跟踪那里有多少活动子上下文,当它达到 0 时关闭上下文。

在做任何这些之前,你应该强烈地重新考虑有这么多上下文的原因。最好只创建两个上下文并使用导入来连接配置文件。对我来说,我看起来像是过度工程。我想不出一个很好的用例来做这样的事情,我很想听听你为什么这样做。

于 2012-10-20T02:52:51.637 回答
0

所以,显然我正在尝试做一些 Spring(至少到 3.1 版)不准备做的事情。

于 2012-11-21T14:13:20.460 回答