spring的启动过程

来源:互联网 发布:气象数据采集仪 编辑:程序博客网 时间:2024/06/10 06:58

spring启动的过程其实就是Ioc容器的启动过程,对于web程序来说,Ioc容器启动即是建立上下文的过程。

spring的启动过程:
1、首先,对于一个web应用,其部署在web容器中,web容器会为其提供一个全局的上下文环境,这个上下文就是ServletContext,为后面的spring Ioc提供宿主环境。


2、在web.xml中会有一个监听器contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInnitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文称为根上下文,即WebApplicationContext

这里写图片描述

     WebApplicationContext这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。WebApplicationContext就是spring的Ioc容器。这个被初始化的上下文作为根上下文存在,这个根上下文载入后,以key-value的形式被绑定在web应用程序的ServletContext中,这样IOC容器中的类就可以在任何地方被访问到了。其对应的Bean定义的配置由web.xml中的context-param标签指定。
比如:

<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>

这里写图片描述



3、contextLoadListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个Servlet可以配置多个,以最常见的DispatcherServlet为例,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。

<!-- springmvc的核心是一个servlet (我们通常称为前端控制器) --><servlet>    <servlet-name>springMVC</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <!-- serlvet配置信息加载springmvc的配置文件 -->    <init-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:springmvc.xml</param-value>    </init-param></servlet><servlet-mapping>    <servlet-name>springMVC</servlet-name>    <url-pattern>/</url-pattern></servlet-mapping>

     DispatcherServlet上下文在初始化的时候会建立自己的Ioc上下文,用以持有Spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会先从 ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。最后把自己持有的这个当下问保存到ServletContext中,供以后检索和使用。

这里写图片描述

     这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是XmlWebApplicationContext。

这里写图片描述

     初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。


那什么是ServletContext呢?
ServletContext是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放。
换种说法,也就是运行在JAVA虚拟机中的每一个Web应用程序都有一个与之相关的Servlet上下文。ServletContext对象是Web服务器中的一个已知路径的根,Servlet上下文被定位于http://localhost:8080/项目名。以 /项目名 请求路径(称为上下文路径)开始的所有请求被发送到与此ServletContext关联的Web应用程序。一个ServletContext对象表示了一个Web应用程序的上下文。


spring上下文容器配置
spring为我们提供了实现ServletContextListener接口的上下文初始化监听器:org.springframework.web.context.ContextLoaderListener
spring为我们提供的IOC容器,需要我们指定容器的配置文件,然后由该监听器初始化并创建该容器。要求你指定配置文件的地址及文件名称,一定要使用:contextConfigLocation作为参数名称。

<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>

ContextLoaderListener的作用?
ContextLoaderListener类它读取web.xml中配置的context-param中的配置文件,提前在web容器初始化前准备业务对应的Application context;将创建好的Application context放置于ServletContext中,为springMVC部分的初始化做好准备。


父上下文(父容器)和子上下文(子容器)
Spring 会创建一个WebApplicationContext上下文,称为父上下文(父容器),保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。
可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);
ContextLoaderListener类它读取web.xml中配置的context-param中的配置文件,提前在web容器初始化前准备业务对应的ApplicationContext;将创建好的ApplicationContext放置于ServletContext中,为springMVC部分的初始化做好准备。

每个DispatchServlet会有一个自己的上下文,称为子上下文,它也保存在 ServletContext中,key 是”org.springframework.web.servlet.FrameworkServlet.CONTEXT”+Servlet名称。当一 个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是 DispatcherServlet.class.getName() + “.CONTEXT”。
可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);

父上下文(父容器)和子上下文(子容器)的访问权限:
子上下文可以访问父上下文中的bean,但是父上下文不可以访问子上下文中的bean。

原创粉丝点击