Servlet对象生命周期(init方法、service方法、destroy方法)

- 默认情况下服务器启动的时候AServlet对象并没有被实例化

  - 用户发送第一次请求的时候,控制台输出了以下内容:

    ```
    AServlet无参数构造方法执行了
    AServlet's init method execute!
    AServlet's service method execute!
    ```

  - 根据以上输出内容得出结论:

    - 用户在发送第一次请求的时候Servlet对象被实例化(AServlet的构造方法被执行了。并且执行的是无参数构造方法。)
    - AServlet对象被创建出来之后,Tomcat服务器马上调用了AServlet对象的init方法。(init方法在执行的时候,AServlet对象已经存在了。已经被创建出来了。)
    - 用户发送第一次请求的时候,init方法执行之后,Tomcat服务器马上调用AServlet对象的service方法。

  - 用户继续发送第二次请求,控制台输出了以下内容:

    ```
    AServlet's service method execute!
    ```

  - 根据以上输出结果得知,用户在发送第二次,或者第三次,或者第四次请求的时候,Servlet对象并没有新建,还是使用之前创建好的Servlet对象,直接调用该Servlet对象的service方法,这说明:

    - 第一:Servlet对象是单例的(单实例的。但是要注意:Servlet对象是单实例的,但是Servlet类并不符合单例模式。我们称之为假单例。之所以单例是因为Servlet对象的创建我们javaweb程序员管不着,这个对象的创建只能是Tomcat来说了算,Tomcat只创建了一个,所以导致了单例,但是属于假单例。真单例模式,构造方法是私有化的。)
    - 第二:无参数构造方法、init方法只在第一次用户发送请求的时候执行。也就是说无参数构造方法只执行一次。init方法也只被Tomcat服务器调用一次。
    - 第三:只要用户发送一次请求:service方法必然会被Tomcat服务器调用一次。发送100次请求,service方法会被调用100次。

  - 关闭服务器的时候,控制台输出了以下内容:

    ```
    AServlet's destroy method execute!
    ```

  - 通过以上输出内容,可以得出以下结论:

    - Servlet的destroy方法只被Tomcat服务器调用一次。
    - destroy方法是在什么时候被调用的?
      - 在服务器关闭的时候。
      - 因为服务器关闭的时候要销毁AServlet对象的内存。
      - 服务器在销毁AServlet对象内存之前,Tomcat服务器会自动调用AServlet对象的destroy方法。

  - 请问:destroy方法调用的时候,对象销毁了还是没有销毁呢?

    - destroy方法执行的时候AServlet对象还在,没有被销毁。destroy方法执行结束之后,AServlet对象的内存才会被Tomcat释放。
    
  - Servlet对象更像一个人的一生:

    - Servlet的无参数构造方法执行:标志着你出生了。
    - Servlet对象的init方法的执行:标志着你正在接受教育。
    - Servlet对象的service方法的执行:标志着你已经开始工作了,已经开始为人类提供服务了。
    - Servlet对象的destroy方法的执行:标志着临终。有什么遗言,抓紧的。要不然,来不及了。

  - 关于Servlet类中方法的调用次数?

    - 构造方法只执行一次。
    - init方法只执行一次。
    - service方法:用户发送一次请求则执行一次,发送N次请求则执行N次。
    - destroy方法只执行一次。

  - 当我们Servlet类中编写一个有参数的构造方法,如果没有手动编写无参数构造方法会出现什么问题?

    - 报错了:500错误。
    - 注意:500是一个HTTP协议的错误状态码。
    - 500一般情况下是因为服务器端的Java程序出现了异常。(服务器端的错误都是500错误:服务器内部错误。)
    - 如果没有无参数的构造方法,会导致出现500错误,无法实例化Servlet对象。
    - 所以,一定要注意:在Servlet开发当中,不建议程序员来定义构造方法,因为定义不当,一不小心就会导致无法实例化Servlet对象。

  - 思考:Servlet的无参数构造方法是在对象第一次创建的时候执行,并且只执行一次。init方法也是在对象第一次创建的时候执行,并且只执行一次。那么这个无参数构造方法可以代替掉init方法吗?

    - 不能。
    - Servlet规范中有要求,作为javaweb程序员,编写Servlet类的时候,不建议手动编写构造方法,因为编写构造方法,很容易让无参数构造方法消失,这个操作可能会导致Servlet对象无法实例化。所以init方法是有存在的必要的。

  - init、service、destroy方法中使用最多的是哪个方法?

    - 使用最多就是service方法,service方法是一定要实现的,因为service方法是处理用户请求的核心方法。
    - 什么时候使用init方法呢?
      - init方法很少用。
      - 通常在init方法当中做初始化操作,并且这个初始化操作只需要执行一次。例如:初始化数据库连接池,初始化线程池....
    - 什么时候使用destroy方法呢?
      - destroy方法也很少用。
      - 通常在destroy方法当中,进行资源的关闭。马上对象要被销毁了,还有什么没有关闭的,抓紧时间关闭资源。还有什么资源没保存的,抓紧时间保存一下。


## GenericServlet

- 我们编写一个Servlet类直接实现Servlet接口有什么缺点?

  - 我们只需要service方法,其他方法大部分情况下是不需要使用的。代码很丑陋。

- 适配器设计模式Adapter

  - 手机直接插到220V的电压上,手机直接就报废了。怎么办?可以找一个充电器。这个充电器就是一个适配器。手机连接适配器。适配器连接220V的电压。这样问题就解决了。

- 编写一个GenericServlet类,这个类是一个抽象类,其中有一个抽象方法service。

  - GenericServlet实现Servlet接口。
  - GenericServlet是一个适配器。
  - 以后编写的所有Servlet类继承GenericServlet,重写service方法即可。

- 思考:GenericServlet类是否需要改造一下?怎么改造?更利于子类程序的编写?

  - 思考第一个问题:我提供了一个GenericServlet之后,init方法还会执行吗?

    - 还会执行。会执行GenericServlet类中的init方法。

  - 思考第二个问题:init方法是谁调用的?

    - Tomcat服务器调用的。

  - 思考第三个问题:init方法中的ServletConfig对象是谁创建的?是谁传过来的?

    - 都是Tomcat干的。
    - Tomcat服务器先创建了ServletConfig对象,然后调用init方法,将ServletConfig对象传给了init方法。

  - 思考一下Tomcat服务器伪代码:

   

- ```java
      public class Tomcat {
          public static void main(String[] args){
              // .....
              // Tomcat服务器伪代码
              // 创建LoginServlet对象(通过反射机制,调用无参数构造方法来实例化LoginServlet对象)
              Class clazz = Class.forName("com.bjpowernode.javaweb.servlet.LoginServlet");
              Object obj = clazz.newInstance();
              
              // 向下转型
              Servlet servlet = (Servlet)obj;
              
              // 创建ServletConfig对象
              // Tomcat服务器负责将ServletConfig对象实例化出来。
              // 多态(Tomcat服务器完全实现了Servlet规范)
             ServletConfig servletConfig = new org.apache.catalina.core.StandardWrapperFacade();
              
              // 调用Servlet的init方法
              servlet.init(servletConfig);
              
              // 调用Servlet的service方法
              // ....
              
          }
      }
      ```

你可能感兴趣的:(JavaWeb,java)