zoukankan      html  css  js  c++  java
  • Servlet 6—— Servlet对象的生命周期

    1、Servlet的本质是什么?

    Servlet是服务器端的小java程序,这个小java程序不能随意编写,必须实现SUN制定的javax.servlet.Servlet接口,实现其中的方法。Servlet是一个满足java规范的java类。Servlet既然满足Servlet规范,Tomcat服务器我们可以叫做“WEB容器(Container)”,那么Servlet 就可以叫做容器中的“组件(Component)”。

    2、关于Servlet对象的生命周期

    • 什么是生命周期?
      • 生命周期表示一个java对象从最初被创建到最终销毁经历的所有过程。
    • Servlet对象的生命周期是谁来管理的?程序员可以干涉吗?
      • Servlet对象的生命周期,javaweb程序员是无权干涉的,包括该Servlet对象的相关方法的调用,javaweb程序员也是无权干涉的。
      • Servlet对象从最初的创建,方法的调用,以及最对象的销毁整个过程,是由WEB容器来管理的。
      • Web Container管理Servlet对象的生命周期。
    • 默认情况下,Servlet对象在WEB服务器启动阶段不会被实例化。【若希望在web服务器启动阶段实例化Servlet对象,需要进行特殊的设置】
    • 描述Servlet对象的生命周期
      • 用户在浏览器地址栏上输入URL:http:// localhost:8080/pnj-servlet-03/testLifeCycle
      • web容器截取请求路径:/servlet-03/testLifeCycle
      • web容器在容器上下文中找请求路径/pnj-servlet-03/testLifecycle对应的Servlet对象
      • 若没有找到相应的Servlet对象
        • 通过web.xml文件中相关的配置信息,得到请求路径/testLifeCycle对应的Servlet完整类名
        • 通过反射机制,调用Servlet类的无参数构造方法完成Senvlet对象的实例化
        • web容器调用Servlet对象的init方法完成初始化操作
        • web容器调用Servlet对象的service方法提供服务
      • 若找到应的Senvlet对象
        • web容器直接调用Servlet对象的service方法提供服务
      • Servlet对象从最初的创建,方法的调用,以及最对象的销毁整个过程,是由WEB容器来管理的。
        • web容器关闭的时候/webapp重新部署的时候/该Servlet对象长时间没有用户再次访问的时候web容器会将该Servlet对象销毁。在销毁该对象之前,web容器会调用Servlet对象的destroy方法,完成销毁之前的准备。
    • Servlet对象是单例,但是不符合单例模式,只能称为伪单例。真单例的构造方法是私有化的,Tomcat服务器是支持多线程的【单实例多线程环境下运行的一个java对象】。所以Servlet对象在单实例多线程的环境下运行的。那么Servlet对象中若有实例变里,并且实例变里涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题,不建议在Servlet对象中使用实例变量,尽量使用局部变量。
    • 若希望在web服务器启动阶段实例化Servlet对象,需要在web.xml文件中进行相关的配置,例如:

      • <?xml version="1.0" encoding="UTF-8"?>
        <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
          <servlet>
            <servlet-name>testLifeCycle</servlet-name>
            <servlet-class>myweb.testLifeCycle</servlet-class>
            <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet-mapping>
            <servlet-name>testLifeCycle</servlet-name>
            <url-pattern>/testLifeCycle</url-pattern>
          </servlet-mapping>
          
           <servlet>
            <servlet-name>WelcomeServlet</servlet-name>
            <servlet-class>myweb.WelcomeServlet</servlet-class>
            <load-on-startup>2</load-on-startup>
          </servlet>
          <servlet-mapping>
            <servlet-name>WelcomeServlet</servlet-name>
            <url-pattern>/WelcomeServlet</url-pattern>
          </servlet-mapping>
        </web-app> 
      • <load-on-startup>1</ load-on-startup>自然数越小优先级越高

    • web.xml文件在服务器启动阶段被解析,若web.xml文件编写有错误,启动Tomcat服务器的时候,当前webapp启动失败。
    • Servlet对象“默认情况”下,在服务器启动阶段是不会实例化的,不会创建对象。
    • 在Servlet类中最好不要手动编写任何构造函数,这样做可能会导致无参数构造函数不存在,这样通过反射机制创建对象的时候,会出现实例化异常。Servlet对象创建失败

    3、Servlet对象的生命周期是什么样的,什么时候创建,创建几次,什么时候销毁?

    • 假设客户端向web服务器发送的请求是/login请求,当用户向web服务器第一次发送/login请求的时候,Tomcat在容器中搜索/login对象的Servlet对象,但是没有找到该对象,此时会从web.xml文件中获取/login对象的完整Servlet类名,通过反射机制,调用Servlet的无参数构造方法创建Servlet对象,马上调用init方法完成Servlet对象的初始化操作,然后调用service方法提供核心服务。
    • 当用户第2+次再发送/login请求的时候,Tomcat还是在容器中搜索/login对象的Servlet对象,此时可以找到该对象,直接调用该对象的service方法提供核心服务。
    • 当用户长时间没有访问该Servlet,或者服务器关闭,或者项目重新部署的时候,Tomcat容器会去回收Servlet对象所占用的内存,在回收该内存之前调用该Servlet对象的destroy方法,完成回收之前的准备。
    • 结论:
      • Servlet类的构造方法只执行一次。
      • Senvlet对象的init方法只执行一次,init方法执行的时候,Servlet对象已经被创建好了。
      • Servlet对象的service方法,只要用户请求一次,则执行一次。service方法执行次数最多,因为在这个方法中需要提供服务,处理当前的请求,这是核心方法,用户访问的每一次都是要执行的。
      • Servlet对象的destroy方法只执行一次,destroy方法执行的时候,Servlet对象还没有被销毁,即将被销毁。
      • 其实init、destroy方法都是SUN公司为javaweb程序员准备的特殊的时刻,初始化时刻/销毁时刻,一般这两个方法中是不需要编写任何代码的,但是在特殊的情况下,例如:需求要求在对象被初始化的那一刻记录日志,那么记录日志的代码就编写到init方法中,例如:需求要求在该Servlet对象被销毁的那一刻记录日志,那么记录日志的代码就需要编写到destroy方法。自然会被服务器调用并执行。

    4、Servlet对象的生命周期由Tomcat容器管理,对象的创建,对象内存的释放,还有对象中的方法调用都是由Tomcat容器完成,程序员不能干涉,只能编写该类实现Servlet接口,将其配置在web.xml文件中。 

    5、Servlet对象是单实例的,并且是在多线程的环境下运行,可能存在线程并发带来的安全问题。

    6、什么情况下在init方法中编写程序?什么情况下在service方法中编写程序?什么情况下在destroy方法中编写程序?

    • init方法是SUN规范中为程序员提供的一个对象初始化时机,这是一个特定的时刻,有的时候我们需要在这个特定的时刻执行一段特定的程序,此时将该程序写入init方法,例如:项目经理要求在Servlet对象创建时刻记录日志,请将该程序编写到init方法中。对象第一次创建的时候执行记录日志,并且只执行一次,记录一次日志信息。(init方法一般很少用)
    • Service方法是Servlet的核心业务方法,核心业务都在该方法中完成,只要编写一个Servletservice方法是一定要编写代码的,完成业务的处理。(常用)
    • destroy方法init方法相同,只不过是一个不同的时机。(destroy方法一般很少使用)

    7、Senxlet对象实例化之后,这个Servlet对象被存储到哪里了?

    大多数的WEB容器都是将该Servlet对象以及对应的url-pattern存储到Nap集合中了。

    在WEB容器中有这样一个Map集合

    Map<String,Servlet>集合

    key value
    /login Loginservlet对象引用
    /delete DeleteServlet对象引用
    /save SaveServlet对象引用

    服务器在启动的时候就会解析各个webapp的web.xml文件,将web.xml文件中的url-pattern和对应的Servlet完整类名存储到Map集合中了。

    8、Servlet接口中的这些方法中编写什么代码?什么时候使用这些方法?

    1. 无参数构造方法【以后就不需要再考虑构造函数了,尽量别动构造函数】
    2. init方法
      • 以上两个方法执行时间几乎是相同的,执行次数都是一次,构造方法执行的时候对象正在创健,init方法执行的时候对象已经创建。
      • 若系统要求在对象创建时刻执行一段特殊的程序,这段程序尽里写到init方法中。
      • 为什么不建议将代码编写到构造函数中呢?存在风险!当程序员编写构造方法的时候,可能会导致无参数构造方法不存在。一个类不编写任何构造函教,默认有一个无参数的构造方法,但是一旦编写一个有参数的构造方法之后,系统则不再提供无参数枸造函数。
      • Servlet中的init方法是SUN公司为javaweb程序员专门提供的一个初始化时刻。若希望在初始化时刻执行一段特殊的程序,这个程序可以编写到init
    3. service方法
      • 这个方法是必然要重写的,因为在这个方法需要完成业务逻辑的处理、请求的处理、以及完成响应。而且这个方法中的代码是最有价值的。
      • 也是最难写的,因为最难编写的就是业务代码啦。
    4. destroy方法
      • 这个方法也是SUN公司为javaweb程序员提供的一个特殊的时刻,这个特殊的时刻被称为对象销毁时刻,若希望在销毁时刻执行一段特殊的代码,需要将这段代码编写到destroy方法,自动被容器调用。
      • 回顾:类加载时刻执行程序,代码写到哪里?编写到静态代码块中。
    5. 结论:sun公司为我们程序员提供了很多个不同的时刻。若在这个特殊时刻执行特殊程序,这些程序是有位置编写的。
    转载请注明出处:https://www.cnblogs.com/stu-jyj3621
  • 相关阅读:
    Java泛型的协变
    【LeetCode】LeetCode——第14题:Longest Common Prefix
    【BZOJ4008】【HNOI2015】亚瑟王 概率DP
    git merge 和 git merge --no-ff
    自己定义View时,用到Paint Canvas的一些温故,讲讲平时一些效果是怎么画的(基础篇 一)
    Spring Boot 集成MyBatis
    .net framework中重新注册IIS
    FireFox插件SQLite Manager的使用
    sqlite developer注册码
    javascript 中用到的时间戳函数
  • 原文地址:https://www.cnblogs.com/stu-jyj3621/p/14354981.html
Copyright © 2011-2022 走看看