Servlet规范一

Servlet规范(一)

一、Servlet基础

宏观地讲,Servlet 是连接 Web 服务器与服务端 Java 程序的协议,是一种通信规范。这个规范是以一套接口的形式体现的。 通常来说,Servlet 是宏观上 Servlet 规范中的一个具体的接口,Servlet 规范中包含一套接口。而 Servlet 接口仅仅是其中之一。 微观地讲,Servlet 是 Servlet 接口实现类的一个实例对象,是运行在服务器上的一段 Java 小程序,即 Server Applet,也就是 Servlet 这个单词的来历。Servlet 的主要功能是根据客户 端提交的请求,调用服务器端相关 Java 代码,完成对请求的处理与运算。 在这里插入图片描述

1.Servlet生命周期

所谓 Servlet 生命周期是指,Servlet 对象的创建、Servlet 对象的初始化、Servlet 对象服 务的执行,及最终 Servlet 对象被销毁的整个过程。
在这里插入图片描述

Servlet 的整个生命周期过程的执行,均由 Web 服务器负责管理。即 Servlet 从创建到服 务到销毁的整个过程中方法的调用,都是由 Web 服务器负责调用执行,程序员无法控制其 执行流程。 但程序员可以获取到 Servlet 的这些生命周期时间点,并可以指定让 Servlet 做一些具体 业务相关的事情。

1.1Servlet生命周期执行流程

在这里插入图片描述

Servlet 生命周期方法的执行流程:

(1)当请求发送到 Web 容器后,Web 容器会解析请求 URL,并从中分离出 Servlet 对应的 URI。

(2)根据分离出的 URI,通过 web.xml 中配置的 URI 与 Servlet 的映射关系,找到要执行的 Servlet,即找到用于处理该请求的 Servlet。

(3)若该 Servlet 不存在,则调用该 Servlet 的无参构造器、init()方法,实例化该 Servlet。 然后执行 service()方法。

(4)若该 Servlet 已经被创建,则直接调用 service()方法。

(5)当 Web 容器被关闭,或该应用被关闭,则调用执行 destroy()方法,销毁 Servlet 实例。

在这里插入图片描述

对于以上代码的运行,注意以下几个时间点:

(1)项目部署后启动服务器,发现并没有执行 Servlet 的无参构造器方法,说明在 Web 容 器启动时并没有创建 Servlet 对象。

(2)用户提交请求后,马上可以看到无参构造器、init()方法、service()方法均执行。

(3)刷新页面,发现只会执行 service()方法,每刷新一次,即每提交一次请求,就会执行 一次 service()方法。 (4)让另外一个浏览器也发出同样的请求,会发现只执行 service()方法,而无参构造器、init() 方法均未执行。 (5)正常关闭 Tomcat(使用 stop server 关闭,不能使用 Terminate 关闭),发现 destroy()方 法也会执行。

1.2Servlet特征

(1)Servlet 是单例多线程的。

(2)一个 Servlet 实例只会执行一次无参构造器与 init()方法,并且是在第一次访问时执行。

(3)用户每提交一次对当前 Servlet 的请求,就会执行一次 service()方法。

(4)一个 Servlet 实例只会执行一次 destroy()方法,在应用停止时执行。

(5)由于 Servlet 是单例多线程的,所以为了保证其线程安全性,一般情况下是不为 Servlet 类定义可修改的成员 变量的。因为每个线程均可修改这个成员变量,会出现线程安全问题。

(6)默认情况下,Servlet 在 Web 容器启动时是不会被实例化的。

1.3Web 容器启动时创建 Servlet 实例

在这里插入图片描述

在中添加的作用是,标记是否在Web服务器(这里是Tomcat) 启动时创建并初始化这个 Servlet 实例,即是否在 Web 服务器启动时调用执行该 Servlet 的无 参构造器方法与 init()方法,而不是在真正访问时才创建。 它的值必须是一个整数。

  • 当值大于等于 0 时,表示容器在启动时就加载并初始化这个 Servlet,数值越小,该 Servlet 的优先级就越高,其被创建的也就越早;

  • 当值小于 0 或者没有指定时,则表示该 Servlet 在真正被使用时才会去创建。

  • 当值相同时,容器会自己选择创建顺序。

1.4Web容器中的两个Map方法

当 Servlet 实例被创建好后被放在了哪里?web.xml 中 URI 与 Servlet 的映射关系反映到 内存中是以什么形式存在呢? 当 Servlet 实例被创建好后,会将该 Servlet 实例的引用存放到一个 Map 集合中。该 Map 集合的 key 为 URI,而 value 则为 Servlet 实例的引用,即 Map<String,value>。当 Web 容器 从用户请求中分离出 URI 后,会首先到这个 Map 中查找是否存在其所对应的 value。若存在, 则直接调用其 service()方法。若不存在,则需要创建该 Servlet 实例。

若请求的 Servlet 实例不存在,Web 容器又是根据什么创建这个 Servlet 实例的呢?在 Web 容器的内存中,还存在一个 Map 集合。该 Map 集合的 key 为 URI,而 value 则为 web.xml 中配置的与之对应的 Servlet 的全限定性类名,即 Map<String,value>。 当Web容器从用户请求中分离出URI后,到第一个Map中又没有找到其所对应的Servlet 实例,则会马上查找这第二个 Map,从中找到其所对应的类名,再根据反射机制,创建这 个 Servlet 实例。然后再将这个创建好的 Servlet 的引用放入到第一个 Map 中

1.5关于getServletInfo方法

Servlet 接口中的方法 getServletInfo(),是由程序没自己定义的有关当前 Servlet 的一些基本信息,不属于Servlet 生命周期中的方法。对程序的运行没有任何影响与作用。仅仅是返 回一些让他人阅读的信息而已。

2.ServletConfig
2.1什么是ServletConfig

在 Servlet 接口的 init()方法中具有唯一的一个参数 ServletConfig。ServletConfig 是个接口, 顾名思义,就是 Servlet 配置,即在 web.xml 中对当前 Servlet 类的配置信息。Servlet 规范将 Servlet 的配置信息全部封装到了 ServletConfig 接口对象中。 在 Web 容器调用 init()方法时,Web 容器首先会将 web.xml 中当前 Servlet 类的配置信息 封装为一个对象。这个对象的类型实现了 ServletConfig 接口,Web 容器会将这个对象传递给 init()方法中的 ServletConfig 参数。

2.2获取ServletConfig对象

由于 ServletConfig 中可以获取到 Servlet 的初始化参数,获取到 ServletContext 对象,而 这些参数与对象在进行业务逻辑处理时,即执行 service()方法时需要经常访问,很重要,所 以 ServletConfig 对象也就显得很重要了。 由于 ServletConfig 对象是 Web 容器通过 init()方法传递给当前 Servlet 类的,而 init()方法 只会在 Servlet 对象初始化时调用一次。所以,需要在 init()方法中将 ServletConfig 对象传递 给 Servlet 的 ServletConfig 成员变量,这样 service()方法即可使用 ServletConfig 对象了。也就 是说,我们需要在 Servlet 中声明一个 ServletConfig 成员变量。 若在 Servlet 中声明一个 ServletConfig 成员变量,是否会存在线程安全问题呢?因为 Servlet 是单例多线程的。只要在 Servlet 中不为 ServletConfig 对象提供其它修改方法,其值 只能由 Web 容器通过 init()方法进行赋值,那么 ServletConfig 对象就不存在线程安全问题。 因为对于所有线程来说,ServletConfig 对象是只读的,不能修改。

2.3ServletConfig中的方法 在这里插入图片描述

在这里插入图片描述
}

  • getInitParameter():获取指定名称的初始化参数值。例如 getInitParameter(“myDBDriver”); 会返回字符串“com.mysql.jdbc.Driver”。

  • getInitParameterNames():获取当前 Servlet 所有的初始化参数名称。其返回值为枚举类 型 Enumeration。

  • getServletName():获取当前 Servlet 的中指定的 Servlet 名 称。如上图中的 ServletName 为“hello-servlet”。

  • getServletContext():获取到当前 Servlet 的上下文对象 ServletContext。这是个非常重要 的对象。

2.4ServletConfig的特征

对于不同的Servlet,Tomcat会为其创建不同的ServletConfig,用于封装各自的配置信息。 也就是说,一个 Servlet 就会有其对应的一个 ServletConfig 对象;有几个 Servlet,将会产生 几个 ServletConfig 对象。

2.5项目部署 在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

运行结论
从对 ServletConfig 对象的输出结果可以看出,Tomcat 容器对 ServletConfig 接口的实现类为 org.apache.catalina.core.StandardWrapperFacade。当然,这个实现类是谁不重要,重要的是要理解,不同的 Web 容器,对该 ServletConfig 的实现类是不同的。但它们的共同特点是, 均实现了 Servlet 规范,实现了 ServletConfig 接口。

想要了解更多内容,欢迎来踩我的博客哟!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值