diff --git a/README.md b/README.md index 24e345e..ac65297 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ - [Netty 高可靠性设计](docs/Netty/AdvancedFeaturesOfNetty/Netty高可靠性设计.md) ## Tomcat +- [servlet-api 源码赏析](docs/Tomcat/servlet-api源码赏析.md) - [一个简单的Web服务器]() - [一个简单的servlet容器]() - [servlet容器详解]() diff --git a/docs/Tomcat/servlet源码赏析.md b/docs/Tomcat/servlet-api源码赏析.md similarity index 91% rename from docs/Tomcat/servlet源码赏析.md rename to docs/Tomcat/servlet-api源码赏析.md index dc4588a..ca8499a 100644 --- a/docs/Tomcat/servlet源码赏析.md +++ b/docs/Tomcat/servlet-api源码赏析.md @@ -1,9 +1,9 @@ ## Servlet 基础 ### Servlet 简介 -Servlet(Server Applet),是用 Java 编写的服务器端程序。其主要功能在于交互式地(Request 和 Response)浏览和修改数据,生成动态 Web内容。Servlet 运行于支持 Java的应用服务器中,如 Tomcat。从实现上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP协议 的 Web服务器。servlet 的工作模式如下: -- 客户端发送请求至服务器; -- 服务器启动并调用相应的 servlet,servlet 根据客户端请求生成响应内容并将其传给服务器; -- 服务器将响应返回客户端; +Servlet(Server Applet)是J2EE的内容之一,由 Java 编写的服务器端小程序。它是web请求的入口,主要功能在于交互式地(Request 和 Response)浏览和修改数据,生成动态 Web内容。Servlet 运行于支持 Java的应用服务器中,如 Tomcat。从实现上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP协议 的 Web服务器。servlet 的工作模式如下: +- 客户端发送请求至 WEB服务器; +- 服务器根据请求的URL调用相应的 servlet对象进行处理,获取到 servlet对象的处理结果; +- 服务器将 响应内容 返回给客户端; 另外,由于各种MVC框架的兴起,现在几乎没人会直接使用 servlet 来处理请求咯,往往都是把 SpringMVC 在 Tomcat 中一配,各种请求都交由 DispatcherServlet 来分发。 @@ -11,9 +11,9 @@ Servlet(Server Applet),是用 Java 编写的服务器端程序。其主要 - 加载 : 客户端第一次访问该 Servlet 时,Tomcat 会创建该 Servlet 的实例,一般只创建1次,所以 servlet对象 在 Tomcat 是单例的; - 初始化 : Tomcat 调用 该 Servlet 的 init()方法 进行初始化; - 服务 : 每当客户端访问 该Servlet 时,Tomcat 就会调用一次该 Servlet 的 service()方法 处理请求; -- 销毁 : Tomcat关闭 或 检测到 该Servlet 要从 Tomcat 删除时,会自动调用 该servlet 的 destroy()方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁; +- 销毁 : Tomcat关闭时,会调用 这些servlet 的 destroy()方法,让该实例释放掉所占的资源。 -简单总结一下就是,只要访问 Servlet,service()方法 就会被调用。init()方法 只有第一次访问 Servlet 的时候才会被调用。destroy()方法 会在 Tomcat 关闭的时候被调用。 +简单总结一下就是:只要访问 Servlet,service()方法 就会被调用,init()方法 只有第一次访问 Servlet 的时候才会被调用,destroy()方法 会在 Tomcat 关闭的时候被调用。 ### <load-on-startup> 在 web.xml 中配置 Servlet 时有个属性 <load-on-startup>1</load-on-startup>。翻译过来就是 “在启动时加载”,其作用如下: @@ -23,17 +23,17 @@ Servlet(Server Applet),是用 Java 编写的服务器端程序。其主要 4. 如果该元素的值为负数或者没有设置,则容器会在 Servlet 被请求时才加载。 ### Servlet的多线程并发问题 -servlet对象 在 Tomcat服务器 是 单实例多线程的,比如 DispatcherServlet对象 只会被创建一次,但多个请求同时过来时,Tomcat线程池 的多个工作线程就会并发地访问该 DispatcherServlet对象。所以,若一个servlet对象中存在被并发修改的共享数据(成员变量 等),又没有加锁控制并发安全,就很可能会出现线程安全问题。 +servlet对象 在 Tomcat服务器中 是 单实例-多线程并发访问的,比如 DispatcherServlet对象 只会被创建一次,但多个请求同时过来时,Tomcat线程池 的多个工作线程就会并发地访问该 DispatcherServlet对象。所以,若一个servlet对象中存在被并发修改的共享数据(成员变量 等),又没有加锁控制并发安全,就很可能会出现线程安全问题。 解决方案: -1. 把使用到共享数据的代码块进行同步(使用synchronized 或 Lock对象); +1. 把可能会并发修改的共享数据的代码块进行同步(使用synchronized 或 Lock对象); 2. 建议在 Servlet类 中尽量不要使用成员变量。若使用成员变量,则必须同步,并尽量缩小同步代码块的范围,以避免因为同步而导致并发效率降低。 ### Servlet 实现请求和响应 -对于每次客户端请求,Web容器 都会创建一个新的 HttpServletRequest请求对象 和 一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给相应的 Servlet对象 的 service()方法,service()方法 再根据请求方式分别调用 doXXX()方法。经过一系列业务层处理,最后将结果封装到 response对象中,交由 Socket对象传输响应给客户端。 +对于每次客户端请求,Web容器 都会创建一个新的 HttpServletRequest请求对象 和 一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给相应的 Servlet对象 的 service()方法,service()方法 再根据请求方式分别调用 doGet()/doPost()/doXXX()方法。经过一系列业务层处理,最后将结果封装到 response对象中,交由 Socket对象传输响应给客户端。 ## Servlet 源码解析 -javax.servlet 包主要对 Servlet 的一些主要行为和接口进行了定义和简单实现,它是 Servlet规范 的体现,具体的实现交由下游厂商或开发者,就像体现了JDBC规范的 java.sql包 一样,主要负责定义标准和规范。其源码和注释如下。 +javax.servlet 包对 Servlet规范 的一些主要行为和接口进行了定义和简单实现,它是 Servlet规范 的体现,具体的实现交由下游厂商或开发者(如:Tomcat / Jetty),就像体现了JDBC规范的 java.sql包 一样,主要负责定义标准和规范。其源码和注释如下。 ```java public interface Servlet { /**