Spring: Relationship between DispacherServlet and WebApplicationContext in ContextLoaderListener

. When configuring Spring in a web container (such as Tomcat), you may already be familiar with the following configuration code in the web.xml file:

[java]  view plain copy  
  1. <context-param>  
  2.         <param-name>contextConfigLocation</param-name>  
  3.         <param-value>/WEB-INF/applicationContext.xml</param-value>  
  4.     </context-param>  
  5.                                
  6.     <listener>  
  7.         <listener-class>  
  8.             org.springframework.web.context.ContextLoaderListener  
  9.         </listener-class>  
  10.     </listener>  
  11.                                                                                                              
  12.     <servlet>  
  13.         <servlet-name>mvc-dispatcher</servlet-name>  
  14.         <servlet-class>  
  15.             org.springframework.web.servlet.DispatcherServlet  
  16.         </servlet-class>  
  17.         <load-on-startup>1</load-on-startup>  
  18.     </servlet>  
  19.                                                                                                                      
  20.     <servlet-mapping>  
  21.         <servlet-name>mvc-dispatcher</servlet-name>  
  22.         <url-pattern>/</url-pattern>  
  23.     </servlet-mapping>  

The above configuration will first create an ApplicationContext in the ContextLoaderListener through applicationContext.xml in <context-param>, and then insert the ApplicationContext into the ServletContext, and achieve this through the setAttribute method of the ServletContext. In the source code of the ContextLoaderListener, we can see to code like this:

[java]  view plain copy  
  1. servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,this.context);  

以上由ContextLoaderListener创建的ApplicationContext是共享于整个Web应用程序的,而你可能早已经知道,DispatcherServlet会维持一个自己的ApplicationContext,默认会读取/WEB-INFO/<dispatcherServletName>-servlet.xml文件,而我么也可以重新配置:

[java]  view plain  copy
  1. <servlet>  
  2.     <servlet-name>  
  3.        customConfiguredDispacherServlet  
  4.    </servlet-name>  
  5.    <servlet-class>  
  6.        org.springframework.web.servlet.DispatcherServlet  
  7.    </servlet-class>  
  8.    <init-param>  
  9.        <param-name>  
  10.            contextConfigLocation  
  11.        </param-name>  
  12.        <param-value>  
  13.            /WEB-INF/dispacherServletContext.xml  
  14.        </param-value>  
  15.    </init-param>  
  16.    <load-on-startup>1</load-on-startup>  
  17. </servlet>  
问题是:以上两个ApplicationContext的关系是什么,它们的作用作用范围分别是什么,它们的用途分别是什么?

ContextLoaderListener中创建ApplicationContext主要用于整个Web应用程序需要共享的一些组件,比如DAO,数据库的ConnectionFactory等。而由DispatcherServlet创建的ApplicationContext主要用于和该Servlet相关的一些组件,比如Controller、ViewResovler等。

对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext,而反过来不行。

在Spring的具体实现上,这两个ApplicationContext都是通过ServletContext的setAttribute方法放到ServletContext中的。但是,ContextLoaderListener会先于DispatcherServlet创建ApplicationContext,DispatcherServlet在创建ApplicationContext时会先找到由ContextLoaderListener所创建的ApplicationContext,再将后者的ApplicationContext作为参数传给DispatcherServlet的ApplicationContext的setParent()方法,在Spring源代码中,你可以在FrameServlet.java中找到如下代码:

[java]  view plain  copy
  1. wac.setParent(parent);  
Among them, wac is the ApplicationContext created by DisptcherServlet, and parent is the ApplicationContext created by ContextLoaderListener. After that, the framework will call the setAttribute() method of the ServletContext to add the wac to the ServletContext.

 

When Spring executes the getBean of the ApplicationContext, if it cannot find the corresponding bean in its own context, it will look for it in the parent ApplicationContext. This also explains why we can get the beans in the ApplicationContext corresponding to the ContextLoaderListener in the DispatcherServlet.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325770020&siteId=291194637