[转]JavaWeb之 Servlet执行过程 与 生命周期
https://www.cnblogs.com/vmax-tam/p/4122105.html
Servlet的概念
什么是Servlet呢?
Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet。Servlet下有一个实现类叫HttpServlet,一个普通的java如果继承了HttpServlet类,覆盖了它的doGet和doPost方法,那么这个普通类也可以叫做Servlet。最后,servlet程序交给服务器运行!
那么,当我们写好了一个Servlet,交给了服务器,它是如何执行的呢!?
Servlet的执行过程
我们写了一个Servlet名叫hello。那么浏览器是如何访问到这个资源呢?
要说这个,我们先来学习一下浏览器的地址输入。
有这样一个输入: http://localhost:8080/day10/hello
http: http协议
localhost: 域名,到本地C盘下的hosts文件查找是否存在域名对应的ip映射记录地址。有的话就直接访问该IP,没有的话就到DNS上去找。
8080 端口号,这里指tomcat服务器。localhost匹配到tomcat的默认站点,到webapps目录下找web应用。
/day10 web应用的名称。在webapps下找是否存在day10的目录。
/hello web资源。在day10web应用下查找是否有这个资源。(如果看不懂,最好先去了解一下tomcat里的文件结构。)
这里/hello 资源就是我们写的一个Servlet,服务器得到这个字符串后就是经过以下过程来找到servlet的!
-> 得到/hello字符串
-> 使用/hello到web.xml文件中查找每一个<servlet-mapping>下的<url-pattern>标签里的内容,然后得到sevlet-name
-> 使用sevlet-name去servlet标签中找到对应的相同名称的servlet配置。
-> 得到servlet配置中的servlet-class内容。字符串:gz.itcast.a_servlet.HelloServlet

<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.vmaxtam.numzero.addServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

最后通过反射实例化HelloServlet对象,然后调用HelloServlet中的方法。
Servlet的映射路径
<url-pattern>/hello</url-pattern> 这里的映射路径还可以用多种方式来填写!
|
url-pattern 浏览器输入URL 精确匹配 /demo1 http://localhost:8080/day10/demo1 /itcast/demo1 http://localhost:8080/day10/itcast/demo1 模糊匹配 /* http://localhost:8080/day10/任意路径 /itcast/* http://localhost:8080/day10/itcast/任意路径 *.后缀名 http://localhost:8080/day10/任意路径.后缀。例如 *.do,*.action, *.html 注意: 1)url-pattern要以/开头,要么以*开头。demo1这种写法是错误的!! 2) /itcast/*.do 这种写法不合法。不能同时使用两种模糊匹配 3)当一个请求有多个servlet被匹配的情况下: a)长的最像的url-pattern会优先被匹配 b)以后缀名结尾的url-pattern优先级最低!!! |
说到这里,就有人问:这个只是在找Servlet文件,那么如果要找服务器的静态文件(html,xml等),服务器的执行过程如何??如果要找的文件不存在又会怎么样?
下面为大家讲解:
缺省路径
在tomcat服务器中有一个默认的Servlet,叫DefaultServlet,DefaultServlet的url-pattern为 / 。这个DefaultServlet的作用主要用于处理静态资源的请求。
输入: http://localhost:8080/day10/test.html 如何找到资源呢?
1)在day10的web应用下查找web.xml文件,用/test.html,存在匹配是否存在符合规则url-pattern,找到就会执行对应的动态资源(servlet)。
2)如果找不到对应的url-pattern,则到day10当前web应用的根目录下查找一个test.html名称的静态资源文件。如果找到这个文件,DefaultServlet读取该静态文件内容输出到浏览器客户端。
3)如果在day10下找不到test.html的静态资源文件,那么返回404的页面。
前面只说到服务器是如何找到Servlet这个文件,那么Servlet是如何执行的呢!!!这就是重点,Servlet的生命周期
Servlet的生命周期
tomcat服务器什么时候创建servlet对象?什么时候销毁对象?什么时候调用了什么方法?!
其实也就是这样的一个过程 :
1.Servlet对象的创建。
2.Servlet对象执行某些方法来给我们服务。
3.Servlet对象的销毁。
而这个过程有4个很核心的方法需要执行:
构造方法: servlet对象创建时调用。默认情况下,第一次访问servlet时,servlet对象创建。只被调 用1次。servlet在tomcat服务器中是单实例的。
init方法: 在创建完servlet对象之后被调用。用于对servlet对象进行初始化。只调用1次。
service方法:每次发出请求时被调用。调用n次。
destroy方法: 在tomcat服务器停止或者web应用重新加载时调用。只调用1次。
下面我们用伪代码来演示一下 浏览器发出请求 到服务器作出相应 整个过程中Servlet的执行过程!
浏览器输入: http://localhost:8080/day10/hello
进入web.html查询资源。
得到字符串 gz.itcast.a_servlet.HelloServlet
模拟tomcat服务器内部的运行代码:
1)用反射构造HelloServlet对象
1.1 得到字节码对象
Class clazz = Class.forName("gz.itcast.a_servlet.HelloServlet ")
1.2 调用无参的构造方法构造对象
Object obj = clazz.newInstance(); ----1.Servlet的构造方法被执行
2)创建ServletConfig对象,调用init方法
2.1 得到init方法对象
Method method = clazz.getDeclareMethod("init",ServletConfig.class);
2.2 执行init方法
method.invoke(obj, config); --2. Servlet的init方法被执行
3)创建request和response对象,调用service方法
3.1 得到service方法对象
Method m = clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
3.2 执行方法
m.invoke(obj,request,response); --3.Servlet的service方法被执行
4)tomcat服务器停止或web应用重新加载时,调用destroy方法
4.1 得到destroy方法对象
Method method = clazz.getDeclareMethod("destroy",null);
4.2 执行方法
method.invoke(obj,null); --4.Servlet的destroy方法被执行
如果文字不够直观,那么我看可以看一下流程图

Servlet对象自动加载
引入
默认情况下,servlet对象会在第一次请求servlet时被创建。创建完之后调用init方法。假如构造方法或者init方法执行的业务逻辑比较多,那么用户在第一次访问servlet时的等待会变长,影响用户的体验。
解决办法
改变servlet的创建时机:让servlet对象在tomcat服务器启动web应用加载时创建。
在servlet的配置中,加入一个配置:
<load-on-startup>正整数</load-on-startup>
|
<servlet> <servlet-name>LifeDemo1</servlet-name> <servlet-class>gz.itcast.c_life.LifeDemo1</servlet-class> <load-on-startup>1</load-on-startup> </servlet> |
注意: 正整数的数值越大,创建的优先级就越低!!
Servlet的多线程安全问题
结论: servlet在tomcat服务器中是单实例多线程的.
多线程并发问题
多个线程之间同时操作了共享数据!!!
解决多线程并发问题
给需要同步的代码块加上唯一的对象锁。
如何编写线程安全的servlet类:
1)尽量不要使用成员变量。
2)如果使用成员变量,要给用到了成员变量的代码块加上锁。尽量缩小同步代码块的范围,以避免因为同步导致执行效率问题。
Init方法
在GenericServlet中提供了一个无参数的init方法!!!
有参数的init:该方法是Servlet的四个生命周期方法中的一个,该方法一定会被服务器调用。在该方法中会调用无参数的init方法。
无参数的init:该方法是Sun公司设计出来方便开发者进行重写,在该方法中实现对servlet对象的初始化工作,这个方法会被有参的init方法调用!
[转]JavaWeb之 Servlet执行过程 与 生命周期的更多相关文章
- JavaWeb之 Servlet执行过程 与 生命周期
Servlet的概念 什么是Servlet呢? Java中有一个叫Servlet的接口,如果一个普通的类实现了这个接口,这个类就是一个Servlet.Servlet下有一个实现类叫HttpServle ...
- Servlet执行流程和生命周期【慕课网搬】
Servlet执行流程(GET方式为例) 首先用户客户端浏览器发出Get方式(点击超链接方式)向浏览器发出请求. 服务器接收到客户端点击超链接,接收到GET请求之后,服务器到WEB.xml中<s ...
- Servlet执行流程和生命周期
Servlet执行流程 Get方式请求HelloServlet ---> <a href="servlet/HelloServlet"> ↓ 服务器在配置文档中查 ...
- .NET MVC执行过程 及 生命周期步骤
1.网址路由比对 2.执行Controller与Action 3.执行View并返回结果 Request 请求到来 IIS 根据请求特征将处理权移交给 ASP.NET UrlRoutingModule ...
- jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
- java的servlet执行过程是怎么样的?
java的servlet执行过程是怎么样 答: Servlet执行过程:程序第一次访问,会调用servlet的init()方法初始化(只执行一次),每次程序执行都会根据请求调用doGet()或者d ...
- HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象
1 HTTP协议特点 1)客户端->服务端(请求request)有三部份 a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...
- JavaEE Servlet 核心方法及生命周期
做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...
- Servlet(API)生命周期
一.最上层接口Servlet 查看Servlet接口源码: 有5个方法 访问过程(默认): 1.进行Servlet类加载 当Tomcat容器启动后,服务器寻找应用部署的描述文件(web.xml),从部 ...
随机推荐
- Elasticsearch 理解
概述 Elasticsearch (ES)是一个基于 Lucene 的开源搜索引擎,它不但稳定.可靠.快速,而且也具有良好的水平扩展能力,是专门为分布式环境设计的. 特性 安装方便:没有其他依赖,下载 ...
- mssql性能优化
总结下SQL SERVER数据库性能优化相关的注意事项,在网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或者过时(可能对SQL SERVER6.5以前的版本或者ORA ...
- mysql增量备份(1/2)
转自:http://www.centos.bz/2012/11/mysql-incremental-backup/ 小量的数据库我们可以每天进行完整备份,因为这也用不了多少时间,但当数据库很大时,我们 ...
- FastGUI for NGUI教程
原地址:http://blog.csdn.net/asd237241291/article/details/8499430 FastGUI是NGUI的一个扩展,所以必须要有NGUI才能使用.FastG ...
- Unity Shader 效果学习
Unity上对于图像的处理,假设单纯使用代码.那么非常遗憾,程序基本会跑死,毕竟是直接对像素的操作,读取写入都是比較耗费CPU和内存的. 所以.这次由于项目须要想实现类似哈哈镜的效果.想来想去,还是认 ...
- Subl 命令
Subl 是sublime 的命令 添加环境变量后可以,在cmd 或者git 下直接 使用subl 进行 打开sublime Example: Subl 打开编辑器 Subl . 将当 ...
- 【Python3 爬虫】12_代理IP的使用
我们在爬取页面的时候,如果长时间使用一个网址去爬取某个网站,就会受爬去限制,此时,我们引用了代理IP,IP随时在变化,也就不会被限制了 一下是国内提供免费代理IP的地址:http://www.xici ...
- Python 的数据表示
一.常量.变量和对象 1.常量:是指在程序的执行过程中不变的量.如:1,2,3,4,……,true.false 也有一些包含在模块中的用符号表示的常量,常用的如math模块中的pi和e,如: > ...
- Docker 使用docker-compose部署项目
原文地址:https://github.com/eacdy/spring-cloud-book/blob/master/3%20%E4%BD%BF%E7%94%A8Docker%E6%9E%84%E5 ...
- 今日头条&58转转笔试
昨天参加今日头条和58转转的笔试,因为时间上有冲突,所以主要选择参加头条的笔试. 先说头条: 头条的题型: 一道改错题 三道编程题 一道设计题 感受: 做题目的的时候还是有点紧张的,因为突然遇到题目需 ...