springMVC原理整理-初始化过程

Web应用的初始化总体过程

当一个Web应用部署到容器(tomcat)内时,在Web应用开始响应执行用户请求前,以下步骤会被依次执行:

  • 部署描述文件(所有web应用启动的初始位置都在web.xml)中,由<listener>元素标记的事件监听器会被创建和初始化。
  • 对于所有事件监听器,如果实现了ServletContextListener接口,将会执行其实现的contextInitialized()方法。(Servlet API提供了监听器,Servlet和Filter的初始化前和销毁后会给实现了ServletContextListener接口的监听器发送通知,采用观察者模式,也称为为订阅-发布模式)
  • 部署描述文件中由<filter>元素标记的过滤器会被创建和初始化,并调用其init()方法。
  • 部署描述文件中由<servlet>元素标记的servlet会根据<load-on-startup>的权值按顺序创建和初始化,并调用其init()方法。

流程图:

对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;

Spring根IOC容器初始化

web容器启动,web.xml中由<listener>元素标记的事件监听器被创建和初始化。contextInitialized()方法被执行,调用父类initWebApplicationContext。

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

1 通过反射创建根IOC容器:XmlWebApplicationContext。

2 调用configureAndRefreshWebApplicationContext:

      1)设置全局上下文到根IOC容器中。

      2)加载spring配置文件:<context-param>标签中param-name为contextConfigLocation 的配置文件,到根IOC容器中。

      3)加载环境配置。

      4)调用refresh()完成各组件初始化。

3 将创建好的根IOC容器放入ServletContext:servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

SpringMVC子IOC容器初始化

从web应用启动总流程可以看出,servlet 在最后一步被初始化。

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

servlet在被初始化的时候会调用其init()方法。

从DispatchServlet类继承关系图中可以知道最终会调用HttpServletBean中init()方法,该初始化方法的主要作用:

将Servlet初始化参数(init-param)设置到该组件上(如contextAttribute、contextClass、namespace、contextConfigLocation),通过BeanWrapper简化设值过程,方便后续使用,同时调用模板方法initServletBean()完成以下操作:

     1 initWebApplicationContext:创建子IOC容器。将ServletContext中name为 org.springframework.web.context.WebApplicationContext.ROOT 的Attribute(根IOC容器)取出,作为父容器。

     2 createWebApplicationContext:通过反射,创建子IOC容器XmlWebApplicationContext,并设置上一步中的根容器作为父容器。

     3 加载环境配置信息。

     4 加载SpringMVC配置文件:<servlet>标签中param-name为:contextConfigLocation。

     5 调用configureAndRefreshWebApplicationContext,最终调用refresh()完成各组件初始化。

最后将创建好的子容器放入ServletContext中:String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac);

 

总结

SpringMVC(源码中大量使用了模板方法模式)的整体初始化过程大致为:

1 web容器启动。

2 Spring根IOC容器初始化:

     2.1)contextLoaderListener监听到容器初始化事件,调用contextInitialized()方法。

     2.2)创建根IOC容器。

     2.3)设置全局上下文到根容器中。

     2.4)加载Spring各项配置。

     2.5)调用refresh方法完成Spring各项配置初始化。

     2.6)将根IOC容器设置到全局上下文环境ServletContext的Attribute中。

3 初始化web.xml中Filter。

4 SpringMVC子IOC容器初始化(web.xml中DispatcherServlet):

     4.1)调用servlet.init方法。

     4.2)初始化参数。

     4.3)创建子IOC容器。

     4.4)加载SpringMVC各项配置。

     4.5)从全局上下文环境ServletContext的Attribute中,取得根IOC容器并设置为父容器,建立父子容器关系。

     4.6)调用refresh方法完成SpringMVC各项组件初始化。

     4.7)将子IOC容器设置到全局上下文环境ServletContext的Attribute中。

 

Filter和Interceptor的本质区别在于:

   Filter是Servlet层面,无法直接注入由容器管理的Bean。

   Interceptor属于SpringMVC层面,可以直接注入由容器管理的Bean。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值