servlet相关源码解析

servlet相关源码解析

一、简介

最近看源码,涉及servlet这一块。借此对servlet及相关源码等知识进行回顾和介绍。通常说的servlet开发其实是一种开发动态网页的解决方案,它包含实现javax.servlet.Servlet接口的servlet程序和解析servlet程序的servlet引擎(即是servlet容器,如tomcat等)。servlet程序是在服务器端运行的。

二、servlet结构

一个servlet是一个在web服务器运行的小程序。

2.1 servlet依赖包

servlet开发依赖包为javax.servlet-api.jar,通常servlet容器中会有(如tomcat),因此打包一般在编译器使用。

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>compile</scope>
</dependency>
2.2 servlet流程
请求
调用
实现
request
servlet容器/引擎
servlet api
servlet程序

servlet引擎和servlet程序通过servlet api通信,流程为:servlet程序实现servlet api接口,外界请求到servlet容器时,servlet容器通过servlet引擎,调用servlet api,实现对servlet程序的调用。

2.3 servlet注册

servlet程序是在web.xml中注册的,包含servlet名称、servlet实现类、servlet请求地址,格式如下

<servlet>
  <servlet-name>servletName</servlet-name>
  <servlet-class>servlet实现类</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>servletName</servlet-name>
  <url-pattern>servlet匹配地址</url-pattern>
</servlet-mapping>
2.3.1 servlet注册位置

通常servlet是在应用程序的web.xml中注册,但其实在servlet容器中(如tomcat), 在conf/web.xml还有个全局的注册(所有应用程序均可使用,控制全局的跳转)。

2.3.2 servlet匹配地址

servlet请求地址可以是固定的一个,也可采用通配符来匹配多个地址,不过采用通配符只能有两种格式:

  • *.扩展名,此时 *前面不能有分割符 / ,这种方式的匹配优先级最低,如: *.html 匹配.html结尾的地址;
  • 以分割符/开头并以*结尾的,如: /stu/ *,匹配所有/stu/开头的地址;

servlet匹配地址采用最具体原则,地址匹配越具体,越优先容易匹配,其中 *.扩展名 模式的匹配优先级最低。

2.3.3 缺省servlet

缺省servlet位于servlet容器中的conf/web.xml中,如果servlet匹配地址为/,则该servlet为缺省servlet,当外界请求地址找不到servlet匹配地址时,就会走缺省servlet。通常访问静态资源(如图片、html等)时,走的就是缺省servlet,即此时不在需要单独配置servlet。

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
		<!--load-on-startup值为0或正数时,值越小,越早被加载,为负数时,则由容器决定加载时机-->
        <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
2.4 servlet类加载

servlet类加载并非完全的双亲委派模式,略有不同,改为当前类加载器优先,目的是对不同web应用间相互隔离(比如不同web应用依赖不同版本的同类jar包,需要相互隔离),这里以tomcat中类加载为例,其类加载器有:

system
bootstrap
common
webapp1
webapp2
webappx
2.4.1 bootstrap

bootstrap类加载器(包含jvm加载器和ExtClassLoader)用于加载jvm核心包(rt.jar)和系统扩展目录下的包(<java_home>/jre/lib/ext)。

2.4.2 sytem

system类加载器(通常为AppClassLoader)加载classpath环境变量设置的指定目录中的类。实际使用(tomcat启动脚本, C A T A L I N A H O M E / b i n / c a t a l i n a . s h ) 中 会 忽 略 原 有 环 境 变 量 的 设 置 , 而 改 为 加 载 CATALINA_HOME/bin/catalina.sh)中会忽略原有环境变量的设置,而改为加载 CATALINAHOME/bin/catalina.sh)CATALINA_HOME/bin/bootstrap.jar、$CATALINA_HOME/bin/tomcat-juli.jar、commons-daemon.jar等jar包。

2.4.3 cmmon

common类加载器加载tomcat内部类和所用webapp 共享的类($CATALINA_HOME/lib).

2.4.4 webapp

webapp类加载器用于加载当前webapp应用程序下的/Web-INF/classes和/Web-INF/lib目录中的class文件和jar包。webapp类加载器仅对当前web应用程序可见。

2.4.5 完整类加载流程

当有类加载需求时,优先在当前应用程序的webapp类加载器加载,若没有,再使用双亲委派,委托common类加载器,commont类加载器接着委托system类加载器,若system类加载器失败,才由common类加载器加载,若common类加载器还是加载失败,则抛异常。

2.5 servlet生命周期
2.5.1 servlet初始化

一个servlet在其生命周期中只会初始化一次,同一个servlet也只会有一个实例。但servlet内的service(HttpServletRequest req, HttpServletResponse resp)方法会被多次调用,每次请求会新生成HttpServletRequest和HttpServletResponse实例。同一个servlet只有一个servlet对象,因此需要注意多线程安全问题。

2.5.2 servlet创建多个实例

servlet实现javax.servlet.SingleThreadModel接口后,可创建多个servlet实例(构成servlet实例池,每次请求使用一个)来处理请求,此时每个请求单独对用一个servlet实例(显然不存在并发引起的问题),当然该接口已经标记为@deprecated(过时),不在推荐使用,而推荐使用多线程同步来处理问题。使用示例如下:

import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
public class SingleServlet extends 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值