【问题标题】:Loading an hierarchy of ApplicationContexts in WebApplicationInitializer在 WebApplicationInitializer 中加载 ApplicationContexts 的层次结构
【发布时间】:2023-03-20 18:35:01
【问题描述】:

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

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

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

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

Root -> AppContext1 -> AppContext2 -> ServletAppContext

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

举个例子:

  • 根定义属性、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 个(Root, 1, 2)。

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

【问题讨论】:

  • 只是出于好奇,你为什么首先需要这么复杂的方案。
  • 这个想法是为了更好地模块化bean(我认为这应该是一个很好的做法)。我觉得不应该很复杂,当然你不能用web.xml来做这个,所以这是一个新的方法。作为奖励,它可以最大限度地减少不符合后处理条件的 bean

标签: java spring spring-mvc servlet-3.0


【解决方案1】:

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

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

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

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

【讨论】:

  • 查看我上面的评论以获得解释
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    相关资源
    最近更新 更多