美文网首页深度解析Spring5源码
52--Servlet知识点回顾以及SpringMVC分析入口

52--Servlet知识点回顾以及SpringMVC分析入口

作者: 闲来也无事 | 来源:发表于2019-02-16 12:52 被阅读15次
    1.Servlet 生命周期
    • Servlet 通过调用 init () 方法进行初始化。
    • Servlet 调用 service() 方法来处理客户端的请求。
    • Servlet 通过调用 destroy() 方法终止(结束)。
    • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

    配置并新建 TestServlet :

    <servlet>
        <servlet-name>myServlet</servlet-name>
        <servlet-class>com.lyc.cn.servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>myServlet</servlet-name>
        <url-pattern>/myServlet</url-pattern>
    </servlet-mapping>
    
    package com.lyc.cn.servlet;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * @author: LiYanChao
     * @create: 2019-02-14 10:21
     */
    public class TestServlet extends HttpServlet {
    
        private String message;
    
        @Override
        public void init() throws ServletException {
            // 执行必需的初始化
            message = "Hello World";
            System.out.println("==TestServlet init");
        }
    
        @Override
        public void destroy() {
            System.out.println("==TestServlet destroy");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 注意这儿的代码,跟下面讲的ServletContextListener有关联,如要运行该段代码,请完整复制整篇内容
            ServletContext servletContext = getServletContext();
            String name = servletContext.getAttribute("name").toString();
            String age = servletContext.getAttribute("age").toString();
            // 设置响应内容类型
            resp.setContentType("text/html");
    
            // 实际的逻辑是在这里
            PrintWriter out = resp.getWriter();
            out.println("<h1>" + name + age + "</h1>");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 设置响应内容类型
            resp.setContentType("text/html");
    
            // 实际的逻辑是在这里
            PrintWriter out = resp.getWriter();
            out.println("<h1>" + message + "</h1>");
        }
    }
    
    1. init
      init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。
      Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
      当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

    2. service
      service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
      每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

    3. doGet和doPost
      GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
      POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

    4. destroy
      destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
      在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

    5. 整体流程

    • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
    • Servlet 容器在调用 service() 方法之前加载 Servlet。
    • 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
    在这里插入图片描述
    (以上描述内容摘自:https://www.runoob.com/servlet/servlet-life-cycle.html
    2.ServletContextListener

    在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法。

    下面通过一个简单的例子来看下ServletContextListener的使用:
    配置并自定义MyServletContextListener

    <listener>
        <listener-class>com.lyc.cn.servlet.MyServletContextListener</listener-class>
    </listener>
    
    package com.lyc.cn.servlet;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    /**
     * @author: LiYanChao
     * @create: 2019-02-14 11:12
     */
    public class MyServletContextListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("MyServletContextListener init...");
            ServletContext servletContext = sce.getServletContext();
            servletContext.setAttribute("name","Jacks");
            servletContext.setAttribute("age","23");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("MyServletContextListener destroyed...");
        }
    }
    

    我们通过实现ServletContextListener并重写其contextInitialized方法,为应用设置了name和age两个属性,并且在servlet中成功读取到了这两个属性。

    3.SpringMVC源码分析入口

    上面回顾了Servlet的一些基本用法和ServletContextListener,为什么要分析ServletContextListener呢? 大家不要忘了在web.xml文件中有:

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

    tomcat在读取web.xml后就会来解析该ContextLoaderListener。我们已经知道ServletContextListener被加载之后会调用其contextInitialized,那么ContextLoaderListener呢?打开其源码我们果然可以发现在该类中也存在contextInitialized方法。从这里也可以看出这两者之前的异曲同工之处,都可以来初始化并配置一些应用上下文的属性。

    来感受一下其源码,简单的一行代码。。。留在下一节分析吧!

    /**
     * Initialize the root web application context.
     */
    @Override
    public void contextInitialized(ServletContextEvent event) {
        initWebApplicationContext(event.getServletContext());
    }
    

    相关文章

      网友评论

        本文标题:52--Servlet知识点回顾以及SpringMVC分析入口

        本文链接:https://www.haomeiwen.com/subject/admbeqtx.html