java servlet 源码_Servlet源码和Tomcat源码解析

画的不好,请将就。。。。

我一般用的IDEA,很久没用Eclipse了,所以刚开始怎么继承不了HttpServlet类,然后看了一眼我创建的是Maven项目,然后去Maven仓库粘贴了,Servlet的坐标进来。

maven坐标获取,直接百度maven仓库,选择第二个。

然后搜索Servlet选择第二个。

创建一个类,不是接口,继承下HttpServlet。

Servlet 接口 :

public interface Servlet {

//负责初始化 Servlet 对象。容器一旦创建好 Servlet 对象后,就调用此方法来初始化 Servlet 对象。 public void init(ServletConfig config) throws ServletException; //负责处理客户的请求并返回响应。当容器接收到客户端要求访问特定的 servlet 请 求时,就会调用 Servlet 的 service 方法 。

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

//Destroy()方法负责释放 Servlet 对象占用的资源,当 servlet 对象结束生命周期时, servlet 容器调用此方法来销毁 servlet 对象。 public void destroy();

//说明:Init(),service(),destroy() 这三个方法是 Servlet 生命周期中的最重要的三个方法。

//返回一个字符串,在该字符串中包含 servlet 的创建者,版本和版权等信息 public String getServletInfo();

//GetServletConfig: 返回一个 ServletConfig 对象,该对象中包含了 Servlet 初始化参 数信息

public ServletConfig getServletConfig(); }

init 方法接收一个 ServletConfig 参数,由容器传入.ServletConfig 就是 Servlet 的配置,在 web.xml 中定义 Servlet 时通过 init-param 标签配置的参数由 ServletConfig 保存

ServletConfig 接口

public interface ServletConfig {

//用于获取 Servlet 名,web.xml 中定义的 servlet-name String getServletName();

//获取 Servlet 上下文对象(非常重要)

ServletContext getServletContext();

//获取 init-param 中的配置参数

String getInitParameter(String var1); //获取配置的所有 init-param 名字集合 Enumeration getInitParameterNames();

}

ServletConfig 是 Servlet 级别,而 ServletContext 是全局的

GenericServlet 抽象类

GenericServlet 是 Servlet 的默认实现,是与具体协议无关的

//抽象类 GenericServlet 实现了 Servlet 接口的同时,也实现了 ServletConfig 接口和 Serializable 这两个接口

public abstract class GenericServlet

implements Servlet, ServletConfig, java.io.Serializable

{

//私有变量,保存 init()传入的 ServletConfig 对象的引用 private transient ServletConfig config;

//无参的构造方法

public GenericServlet() { }

------------------------------------

以下方法实现了 servlet 接口中的 5 个方法

实现 Servlet 接口方法开始

------------------------------------

/*

实现接口 Servlet 中的带参数的 init(ServletConfig Config)方法,将传递的

ServletConfig 对象的引用保存到私有成员变量中,

使得 GenericServlet 对象和一个 ServletConfig 对象关联. 同时它也调用了自身的不带参数的 init()方法

**/

public void init(ServletConfig config) throws ServletException { this.config = config;

this.init(); //调用了无参的 init()方法

}

//无参的 init()方法

public void init() throws ServletException {

}

//空实现了 destroy 方法

public void destroy() { }

//实现了接口中的 getServletConfig 方法,返回 ServletConfig 对象 public ServletConfig getServletConfig()

{

return config; }

//该方法实现接口中的 ServletInfo,默认返回空字符串 public String getServletInfo() {

return ""; }

//唯一没有实现的抽象方法 service(),仅仅在此声明。交由子类去实现具体的应用 //在后来的 HttpServlet 抽象类中,针对当前基于 Http 协议的 Web 开发,HttpServlet

抽象类具体实现了这个方法 //若有其他的协议,直接继承本类后实现相关协议即可,具有很强的扩展性

public abstract void service(ServletRequest req, ServletResponse res) throws

IOException; ------------------------------------

实现 Servlet 接口方法结束 ------------------------------------

--------------------------------------------- 以下四个方法实现了接口 ServletConfig 中的方法 实现 ServletConfig 接口开始

---------------------------------------------

ServletException,

//该方法实现了接口中的 getServletContext 方法,用于返回 servleConfig 对象中所包含的 servletContext 方法

public ServletContext getServletContext() { return getServletConfig().getServletContext();

}

//获取初始化参数

public String getInitParameter(String name) {

return getServletConfig().getInitParameter(name); }

//实现了接口中的方法,用于返回在 web.xml 文件中为 servlet 所配 置的全部的初始化参数的值

public Enumeration getInitParameterNames() {

return getServletConfig().getInitParameterNames();

//获取在 web.xml 文件中注册的当前的这个 servlet 名称。没有在 web.xml 中注册的 servlet,该方法直接放回该 servlet 的类名。

//法实现了接口中的 getServletName 方法 public String getServletName() {

return config.getServletName(); }

--------------------------------------------- 实现 ServletConfig 接口结束

---------------------------------------------

public void log(String msg) { getServletContext().log(getServletName() + ": "+ msg);

}

public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t);

} }

还有最底层的HttpServlet,这个就不说了,说下Tomcat的底层源码。

Server

Server 服务器的意思,代表整个 tomcat 服务器,一个 tomcat 只有一个 Server

Server 中包含至少一个 Service 组件,用于提供具体服务。这个在配置文件中也得到很 好的体现(port=“8005” shutdown="SHUTDOWN"是在 8005 端口监听到"SHUTDOWN"命 令,服务器就会停止)

Service

Service 中的一个逻辑功能层, 一个 Server 可以包含多个 Service

Service 接收客户端的请求,然后解析请求,完成相应的业务逻辑,然后把处理后的结 果返回给客户端,一般会提供两个方法,一个 start 打开服务 Socket 连接,监听服务端口, 一个 stop 停止服务释放网络资源。

Connector

称作连接器,是 Service 的核心组件之一,一个 Service 可以有多个 Connector,主要是 连接客户端请求,用于接受请求并将请求封装成 Request 和 Response,然后交给 Container 进 行处理,Container 处理完之后在交给 Connector 返回给客户端。

Container

Service 的另一个核心组件,按照层级有 Engine,Host,Context,Wrapper 四种,一个 Service 只有一个 Engine,其主要作用是执行业务逻辑

Engine

一个 Service 中有多个 Connector 和一个 Engine,Engine 表示整个 Servlet 引擎,一个 Engine 下面可以包含一个或者多个 Host,即一个 Tomcat 实例可以配置多个虚拟主机,默认 的情况下 conf/server.xml 配置文件中 定 义了一个名为 Catalina 的 Engine。

一个 Engine 包含多个 Host 的设计,使得一个服务器实例可以承担多个域名的服务 1.6 Host

代表一个站点,也可以叫虚拟主机,一个 Host 可以配置多个 Context,在 server.xml 文 件 中 的 默 认 配 置 为 , 其中 appBase=webapps, 也就是\webapps 目录, unpackingWARS=true 属性指定在 appBase 指定的目录中的 war 包都自动的解压, autoDeploy=true 属性指定对加入到 appBase 目录的 war 包进行自动的部署。

Context

Context,代表一个应用程序,就是日常开发中的 web 程序,或者一个 WEB-INF 目录以 及下面的 web.xml 文件,换句话说每一个运行的 webapp 最终都是以 Context 的形式存在, 每个 Context 都有一个根路径和请求路径;与 Host 的区别是 Context 代表一个应用,如,默 认配置下 webapps 下的每个目录都是一个应用,其中 ROOT 目录中存放主应用,其他目录 存放别的子应用,而整个 webapps 是一个站点。

Tomcat的启动流程

tomcat 的启动流程很标准化,入口是 BootStrap,统一按照生命周期管理接口 Lifecycle 的定义进行启动。首先,调用 init()方法逐级初始化,接着调用 start()方法进行启动,同时, 每次调用伴随着生命周期状态变更事件的触发。

启动文件分析

Startup.bat

catalina.bat

set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar" set MAINCLASS=org.apache.catalina.startup.Bootstrap

set ACTION=start

Bootstrap

main 方法是整个 tomcat 启动时的入口。在 main 方法中,使用 bootstrap.init()来初始化 类加载器和创建 Catalina 实例,然后再启动 Catalina 线程

bootstrap.init()方法 用于初始化容器相关,首先创建类加载器,然后通过反射创建

org.apache.catalina.startup.Catalina 实例。

Catalina

Lifecycle 接口

Lifecycle 提供一种统一的管理对象生命周期的接口。通过 Lifecycle、LifecycleListener、

LifecycleEvent

Catalina 实现了对 tomcat 各种组件、容器统一的启动和停止的方式。

在 Tomcat 服务开启过程中启动的一些列组件、容器,都实现org.apache.catalina.Lifecycle 这个接口,其中的 init()、start() 方法、stop() 方法,为其子类实现了统一的 start 和 stop 管理。

load 方法解析

server.xml 配置文件:

并加载 Server、Service、Connector、Container、Engine、 Host、Context、Wrapper 一系列的容器,加载完成后,调用 initialize()来开启一个新的 Server

Digester 类:

解析 server.xml 文件

demon.start()

demon.start()方法会调用 Catalina 的 start 方法

Catalina 实例执行 start 方法。这里有两个点,一个是 load()加载 server.xml 配置、初始 化 Server 的过程,一个是 getServer().start()开启服务、初始化并开启一系列组件、子容器的 过程

StandardServer

service.initialize()

然后拿到 StandardServer 实例调用 initialize()方法初始化 Tomcat 容器的一系列组件。一 些容器初始化的的时候,都会调用其子容器的 initialize()方法,初始化它的子容器。顺序是 StandardServer、StandardService、StandardEngine、Connector。每个容器都在初始化自身相 关设置的同时,将子容器初始化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值