我正在使用 Servlet 3 (Tomcat 7) + Spring 3.1,并尝试使用 WebApplicationInitializer 加载我的 webapp。
在我见过的常见示例中,您有一个加载了 ContextLoaderListener 的 Root ApplicationContext 和一个加载了 DispatcherServlet 的 servlet ApplicationContext。
(明确地说,我不是在谈论 web.xml,而是在 WebApplicationInitializer 内部以编程方式谈论)。
现在,我想要一个 ApplicationContext 的层次结构,比方说:
根 -> AppContext1 -> AppContext2 -> ServletAppContext
-> 表示父 -> 子关系。每个 AppContext 都可以访问自己的 bean 及其祖先的 bean。
举个例子:
- Root 定义属性、DAO 和 TX。
- AppContext1 定义 JPA 和 Spring Data 存储库。
- AppContext2 定义 JMS 和 Spring 集成管道。
- ServletAppContext 定义 Controller 和 View 。
我的第一个方法是将 Root ApplicationContext 添加到 ContextLoaderListener,然后将其设置为 AppContext1 的父级。将 AppContext1 设置为 AppContext2 的父级。将 AppContext2 设置为 ServletAppContext 的父级。最后将 ServletAppContext 与 DispatcherServlet 相关联。
问题是,在关闭时,DispatcherServlet 会关闭 ServletAppContext,但它不会传播。 AppContext1 和 AppContext2 永远不会关闭,因为它们的 bean 永远不会被释放。所以我猜我使用了错误的方法。
我尝试将 AppContext2 关联到 ContextLoaderListener 而不是 Root。在这种情况下,AppContext2 关闭,但 AppContext1 和 Root 保持打开状态。
我也不能有 3 个 ContextLoaderListener,每个 AppContext(Root、1、2)1 个。
我的问题是,对于这种情况,正确的方法是什么?我愿意接受建议。
最佳答案
不关闭父上下文的默认行为是因为单个父上下文可以由多个子上下文共享。在这种情况下,只有在关闭所有子上下文后才能关闭父上下文。
如果它是线性关系(即,每个上下文只有一个 child ),那么您可以使用扩展的 ApplicationContext 实现,其关闭方法也调用父关闭。
如果它不是线性关系——那么你可以实现一个引用计数机制来跟踪有多少活跃的子上下文,当它达到 0 时关闭上下文。
在做任何这些之前,你应该认真地重新考虑有这么多上下文的原因。最好只创建两个上下文并使用导入来连接配置文件。对我来说,我看起来像是过度工程。我想不出做这样的事情的好用例,我很想听听你为什么这样做。
关于java - 在 WebApplicationInitializer 中加载 ApplicationContext 的层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12984380/