上下文分类
Servlet上下文【ServletContext
【容器】】:由Servlet容器初始化,为项目提供宿主环境,例如Tomcat,在web项目启动的时候他就初始化这样的上下文环境,为后续的Spring容器,SpringMvc容器提供宿主环境。这里指的是Tomcat容器里的上下文。
spring上下文【WebApplicationContext
】:是SpringMvc servlet的父级上下文,也称根上下文。当我们启动Spring的时候,那么就需要初始化IOC容器,而这个上下文就是用于管理这些bean,把他们放到容器里。
SpringMvc上下文:DispatchServlet
初始化的时候会创建自己的上下文,并从ServletContext
中取出WebApplicationContext
作为自己上下文的父容器。
其他上下文:servlet可以有多个,自然也存在多个上下文。
web.xml加载顺序
加载顺序:ServletContext【容器】->Listener->Filter->Servlet
- 对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是
ServletContext
【容器】,其为后面的spring IoC容器提供宿主环境; - 容器调用
web.xml
中配置的ContextLoaderListener
,初始化WebApplicationContext
上下文环境(即IOC容器),加载context-param
指定的配置文件信息到IOC容器中。WebApplicationContext
在ServletContext
中以键值对的形式保存 。WebApplicationContext
被称为根上下文spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE
为属性Key,将其存储到ServletContext
中,便于获取。 - 容器初始化
web.xml
中配置的servlet
,为其初始化自己的上下文信息ServletContext
,并加载其设置的配置信息到该上下文中。将WebApplicationContext
设置为它的父容器。以Spring MVC中的DispatcherServlet
为例,这个servlet
实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet
上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet
自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE
先从ServletContext
中获取之前的根上下文(即WebApplicationContext
)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。 - 此后的所有servlet的初始化都按照3步中方式创建,初始化自己的上下文环境,将
WebApplicationContext
设置为自己的父上下文环境。当初始化完毕后,这些上下文也会存到ServletContext
中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。
Spring 容器中的上下文
Spring中容器存在父子关系,父容器不能访问子容器的资源,而子容器可以访问父容器的资源。这样springMVC的上下文就可以获取父容器的Bean来初始化自己的Bean。该如何理解子容器可以访问父容器对象,而父容器不可以访问子容器对象? 最典型的是Web层的congtroller定义的类中,可以引用service层的对象(的接口),相反则不成立。
DispatchServlet
创建的上下文中加载了包含WEB组件的bean,如控制器,视图解析器,以及处理器映射。
ContextLoaderListener
创建的上下文加载驱动后端中间层和数据层组件。
切记不可重复注入,否则就会出现取到两个bean的情况,原因就是在两个容器中注入了bean。