-
多个 WebApplicationContext之祸
在SpringMVC程序中,存在多个WebApplicationContext,如parent WebApplicationContext是从applicationContext.xml中加载的, child WebApplicationContext是从servlet-context.xml中加载的。
通常web.xml配置如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
与类加载器有点相似,child WebApplicationContext当中的bean, 可以访问到parant WebApplicationContext中的bean,但是反过来却不行。
parent是从Listener加载的,而child是从Servlet加载的。
其结构如下图:
1. 通过此方式获取到的WebApplicationContext就是parent
request.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)
2. 通过此方式获取到的WebApplicationContext就是child
request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE)
可以分别通过父、子ApplicationContext,访问彼此的bean(ApplicationContext.getBean),会发现确实子Context可以访问父Context创建的bean , 但父Context却不能访问子Context中的bean。 各个访问自己的bean没有问题。在自动注入@AutoWried的时候,也会是这样。所以使用时一定要注意。