从Servlet到SpringMVC演变过程详解(ServletContext 和WebApplicationContext, ApplicationContext给你安排上了)

无图言屌:

å¾ 1 . Tomcat 容å¨æ¨¡å

以前我们用servlet进行编程:

所有的配置都会在配置在web.xml里面,其实类似于现在的任务编排

我们会把我们的Filter和Servlet还有Listener,初始化的一些参数都写到web.xml中,

然后相信大家也都看到了上面的这张图,里面有两个Context,这两个都是servletcontext,对应的是两个web应用,一个servletcontext对应的是一个web应用,里面会存放这个应用中所有的servlet会共同用到的信息,以及web.xml里面的信息都会在里面存储。servletContext加载的顺序是,Listener->Filter->Servlet

  1. 相信大家也都知道了,当我们发送一个请求的时候,和我们自己的web应用相关的,tomcat会先加载我们web.xml.其实在tomcat的配置目录下面也有一个默认的web.xml,也会被tomcat读取并加载。我们的程序可以自定义的三个环节,就是Listener, Filter和Servlet。
  2. Servlet先加载Listener,ServletContextListener接口能够监听ServletContext对象的生命周期,因为每个web应用仅有一个ServletContext对象,故实际上该接口监听的是整个web应用。
  3. 然后会先经过我们的Filter过滤器链,当然我们也可以实现或者继承Fillter相关的接口或雷,编写我们自己的Filter,然后配置在我们的Web.xml里面,容器就会在读取web.xml时候,加载我们的配置信息进ServletContext(Context是上下文不是容器)
  4. 然后才会根据请求的uri找到我们对应的Servlet处理我们的request请求,最后返回我们的response请求。

后来我们使用了SpringMVC进行编程:

但是我们仍然是基于Tomcat提供的容器的,所以我们的大致流程还是需要在web.xml进行注册,但是我们的程序怎么从Servlet进入到Spring的MVC的写Controller用@Controller和@RequestMapping时代的呢?

其实Spring算是一个独立的世界,Servlet是另外一个世界,从一个世界到另外一个世界就需要一个桥,代理,分发器叫什么都好?无所谓。

SpringMVC有自己的Filter规则,所以有了在web.xml中加入了如下配置:

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

 <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-application.xml</param-value>
</context-param>
   
<filter>
      <filter-name>springSecurityFilterChain</filter-name>
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

 从上面的流程我们可以知道,在这里我们配置了一个ContextLoaderListener,org.springframework.web.context.ContextLoaderListener类实现了javax.servlet.ServletContextListener接口。ServletContextListener接口能够监听ServletContext对象的生命周期,因为每个web应用仅有一个ServletContext对象,故实际上该接口监听的是整个web应用。

  1. 根据执行顺序,Tomcat容器先加载web.xml生成ServletContext,
  2. 然后加载ContextLoaderListener,这个listener是Spring的,他的首要任务就是实例化一个WebApplicationContext,在ServletContext里面注册为key为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE=“WebApplicationContext.ROOT”, value为实例化出来的WebApplicationContext,对象将无论是注解形式的还是基于xml配置的bean加载到WebApplicationContext中。供后面使用。
  3. DelegatingFilterProxy就是从源生的Filter到Spring内部所需要的Filter的桥,比如SpringSecurity里面涉及到的Filter,至于怎么实现的,肯定是通过webApplicationContext加载的啦,
  4. 从Servlet到SpringMVC的Controller 这个桥是DispatcherServlet,之前我们的Servlet是一个Servlet对应一个uri,但是我们的Controller中是一个Method对应一个uri,但是不用担心因为spring有对应的HandlerAdapter:RequestMappingHandlerAdapter这个HandlerAdapter他有个protected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception 方法负责解决这个。

大家记住Spring的东西是通过Spring中的ApplicationContext获取的,这也是为什么Spring的两个特性IOC控制反转 DI依赖注入的牛逼的地方,

总结一下:

  • ServletContext是对应于整个应用的所有的Servlet的公共资源,对应的是web.xml, 
  • ApplicationContext对应的是Spring的整个公共资源,对应的文件时ApplicationContext.
  • WebApplicationContext其实是SpringMVC的,也是ApplicationContext的一种,是对应的web的而已。一般web项目中会形成两个Context,一个是ServletContext这个是容器的上下文,一个是WebApplicationContext是Spring环境中的上下文,而且两者彼此可以相互get到对方,你中有我我中有你,如servletContext.get("WebApplicationContext.ROOT")获得WebApplicationContext实例, WebApplicationContext.getServletContext()获得ServletContext对象

以上我们还写Web.xml,可是后来逐渐地不知道什么时候我们开始不去写web.xml了,逐渐的我们的封装程度越来越高,导致我们距离基础越来越远了,用起来糊里糊涂的.但是无论我们还写不写web.xml,web应用的整个启动流程是这样的保持不变,这些环节和顺序是这样的, 关于web.xml为什么消失了,大家可以参考下面链接:Spring 揭秘 -- 寻找遗失的 web.xml - 徐靖峰|个人博客

参考:

https://wiki.jikexueyuan.com/project/spring-security/filter.html

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值