根上下文和调度程序 servlet 上下文到底是如何进入 Spring MVC Web 应用程序的?
Posted
技术标签:
【中文标题】根上下文和调度程序 servlet 上下文到底是如何进入 Spring MVC Web 应用程序的?【英文标题】:How exactly are the root context and the dispatcher servlet context into a Spring MVC web application? 【发布时间】:2015-08-18 19:53:22 【问题描述】:我正在学习Spring MVC,我有一些疑问
所以,我有这个配置类来配置处理用户请求的 DispatcherServlet:
public class MyWebAppInitializer implements WebApplicationInitializer
@Override
public void onStartup(ServletContext container)
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = ...
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("main", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("main/");
DispatcherServlet 的工作原理对我来说非常清楚。我的疑问与 context 概念有关。
1) 上下文究竟代表什么?我认为这就像一组具有特定用途的豆子,并且可以在环境中协同工作。但我对这个断言绝对不正确。
2) 根上下文和dispatcher servlet上下文有什么区别?
3) 据我了解,dispatcherContext 中定义的 bean 可以访问 rootContext 中定义的 bean(但反之则不然)。为什么?
Tnx
【问题讨论】:
你的 WAR 文件就是上下文。ContextLoaderListener
加载的 Beans/configuraiton 是根上下文,DispatcherServlet
(或 Spring-WS 的 MessageDispatcherServlet
)加载的所有内容都是子上下文。您可以拥有多个 servlet,它们都可以访问根上下文(应该包含共享资源,如服务等)。现在,如果您有 10 个调度程序 servlet,根上下文应该访问哪个 servlet?因此,只有父母可以从孩子那里访问,而不是相反。这也会导致 AOP 出现问题,突然间,子级定义的 AOP 会影响父级。
@M.Deinum Tnx 这么多,完美的解释。如果你把它作为回应我会接受它:-)
***.com/questions/19619539/…
link1 , link2 有很好的解释。
【参考方案1】:
根上下文
Spring 应用程序中的根上下文是由ContextLoaderListener
加载的ApplicationContext
。此上下文应具有全球可用的资源,如服务、存储库、基础设施 bean(DataSource
、EntityManagerFactory
s 等)等。
ContextLoaderListener
在名称 org.springframework.web.context.WebApplicationContext.ROOT
下的 ServletContext
中注册此上下文。
如果您自己加载一个ApplicationContext
并在ServletContext
中使用上面的名称注册它,那么它将成为根上下文。
子上下文
Spring 应用程序中的子上下文是由DispatcherServlet
加载的ApplicationContext
(或者例如Spring-WS 应用程序中的MessageDispatcherServlet
)。此上下文应仅包含与该上下文相关的 bean,对于 Spring MVC,应为 ViewResolver
s、HandlerMapping
s 等。
servlet 在名称 org.springframework.web.servlet.FrameworkServlet.CONTEXT.<servlet-name>
下的 ServletContext
中注册此上下文。
根
只有子上下文可以访问父上下文,因为您可以有多个子上下文。例如在 Spring MVC 中结合 Spring WS 应用程序。父上下文由子级通过在具有众所周知的名称的ServletContext
中找到它来检测。
如果根上下文可以访问子上下文,它将使用哪一个来连接 bean?除此之外,如果是这种情况,当涉及 AOP 时,您也会得到令人惊讶的结果。在子上下文中定义的 AOP 会突然影响在根上下文中配置的 bean。
【讨论】:
太棒了!,非常简洁的解释。 您能否提供任何示例如何实现 1 个根上下文和 2 个子上下文? 答案中已经提到过,例如 Spring MVC 和 Spring WS 的结合。但是,也没有什么可以阻止您创建多个 DispatcherServlet 实例。以上是关于根上下文和调度程序 servlet 上下文到底是如何进入 Spring MVC Web 应用程序的?的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 中使用多个调度程序 Servlet/Web 上下文
Spring MVC 调度程序 xml 和应用程序上下文 xml