javaweb-servlet-继承关系以及service方法、servlet生命周期

发布于:2025-04-19 ⋅ 阅读:(18) ⋅ 点赞:(0)

1.Servlet的继承关系 

1.Servlet的继承关系
    1.继承关系 三者可以根据ctrl+鼠标左键进入
      javax.servlet.Servlet接口:(下面有个抽象类)
        javax.servlet.GenericServlet抽象类(这个抽象类又包含了)
          javax.servlet.Http.HttpServlet抽象子类(也是个抽象子类)

     2.相关方法
        javax.servlet.Servlet接口:
            void init(config)--初始化方法
            void service(request,respon) -服务方法
            void destroy()      --销毁方法

        javax.servlet.GenericServlet抽象类中:
            void service(request,respon) -仍然是抽象的

        javax.servlet.Http.HttpServlet抽象子类:
            void service(request,respon) -不是抽象的
            1. String method=req.getMethod();获取请求的方式
            2. 各种if判断,根据请求方式不同,决定去调用不同的do方法
            (ctrl+F12快速找到)
                  if (method.equals("GET")) {
                      this.doGet(req, resp);
                    } else if (method.equals("HEAD")) {
                      this.doHead(req, resp);
                    } else if (method.equals("POST")) {
                        this.doPost(req, resp);
                    }else {
                        String errMsg = lStrings.getString("http.method_not_implemented");
                        Object[] errArgs = new Object[]{method};
                        errMsg = MessageFormat.format(errMsg, errArgs);
                        resp.sendError(501, errMsg);
                    }

            3. 在HttpServlet这个抽象类中,do方法都差不多:
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                String msg = lStrings.getString("http.method_get_not_supported");
                this.sendMethodNotAllowed(req, resp, msg);
            }
        private void sendMethodNotAllowed(HttpServletRequest req, HttpServletResponse resp, String msg) throws IOException {
                String protocol = req.getProtocol();
                if (protocol.length() != 0 && !protocol.endsWith("0.9") && !protocol.endsWith("1.0")) {
                    resp.sendError(405, msg);
                } else {
                    resp.sendError(400, msg);
                }

            }

     3.小结
            1) 继承关系:HttpServlet -> GenericServlet ->Servlet
            2) Servlet中核心方法:init(),servlet(),destroy()
            3) 服务方法:当有请求过来时,service方法会自动响应(其实都是tomcat容器调用的)
                    在HttpServlet中我们会去分析请求的方式:到底是get、post、head还是delete等
                    然后再决定调用的是哪个do开头的方法
                    那么在HttpServlet中这些do方法默认都是405的实现风格--要我们去子类实现对于的方法,否则默认会报405错误
            4) 因此,我们在新建Servlet,我们才会去考虑请求方法,从而决定重写哪个do方法

2.Servlet的生命周期

1)生命周期:从出生到死亡的过程就是生命周期。对于Servlet中的三个方法:init()、service()、destory()
2)默认情况下:
        第一次接受请求时:这个Servlet会进行实例化(调用构造方法)、初始化(调用init())、然后服务(调用service()
        从第二次请求开始,每一次刷新都是一次服务
        当容器关闭时,其中的所有servlet实例会被销毁,调用销毁方法
3)所以Servlet实例tomcat只会创建一个,所有的请求都是这个实例去响应
    默认情况下,第一次请求时,tomcat才会去实例化,初始化然后再服务。这样的好处-->提高系统的启动速度
                                                             坏处-->第一次请求时耗时太长,对第一个人不公平
因此得出:如果要提高系统的启动速度,当前默认情况就是这样;如果要提高响应速度,我们应该设置Servlet的初始化时机
4)Servlet的初始化时机:
    默认是第一次接受请求时,实例化、初始化
    我们可以通过<load-on-startup>(在web.xml里面配置)来设置servlet启动的先后顺序,数字越小,越靠前
    这样的话随着tomcat启动已经完成了初始化
    <servlet>
            <servlet-name>Demo02Servlet</servlet-name>
            <servlet-class>com.atguigu.servlets.Demo02Servlet</servlet-class>
            <load-on-startup>1</load-on-startup>
    </servlet>

5)Servlet在容器中是:单例的(不管是谁访问创造一个实例)、线程不安全的(一个线程在正常访问资源1的时候,但突然另一个线程把资源1改变了,导致刚才的线程无法正常访问)
    -单例:所有的请求都是同一个实例去响应
    -线程不安全:一个线程需要根据这个实例中的某个成员变量值取做逻辑判断,但是在中间某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发生了变化
    -我们已经知道了servlet是线程不安全的,所以尽量不要在servlet中定义成员变量。如果不得不去定义,那么(1)不要去修改成员变量的值 (2)不要去根据成员变量的值做一些逻辑判断

 


网站公告

今日签到

点亮在社区的每一天
去签到