程序员都应了解的 CDN 是什么?

作者 | 曾建

责编 | 刘静

出品 | CSDN(CSDNnews)

在互联网有一个“8秒原则”,即如果有一个页面的响应时间超过8秒,那么大部分的用户就会放弃加载,从而放弃使用该页面或网站。淘宝,京东,苏宁等电商每天都有成千上万的访问量,在618电商节,双十一购物逛欢节更是具有数以万计的秒杀活动,是什么能够支撑系统在如此高并发情况下还能正常运行?这就不得不提CDN了,CDN是什么呢,让我们一探究竟。

CDN是什么?

CDN其全称是Content Delivery Network,即内容分发网络。

CDN是构建在网络上的内容分发网络,具备内容存储和分发两个关键要素。其基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

比如说,北京的用户让他访问北京的节点,上海的用户让它访问上海的节点,而不是北京的用户访问上海的节点,上海的用户访问北京的节点,这样会极大增加用户的访问时长,及访问的成本。通过就近访问,加速用户对网站的访问,解决Internet网络拥堵状况,提高用户访问网络的响应速度。

CDN就像网络中的快递小哥,把你网购的商品从最近的仓库拿出并选择最优的路线,并将包裹及时的送到指定收货地点。

CDN就是扮演护航及加速的角色,使得每一个网络请求能够请求更快,时延更小,响应更快,带来更为极致的用户体验。当我们在浏览器访问一个页面的时候,

CDN是如何发挥自己的作用呢?

主要有以下步骤,如图:

1. 当用户点击网站页面上的内容URL,经过本地DNS系统解析,DNS系统会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器;

2. CDN的DNS服务器将CDN的全局负载均衡设备IP地址返回用户;

3. 用户向CDN的全局负载均衡设备发起内容URL访问请求;

4. CDN全局负载均衡设备根据用户IP地址,以及用户请求的内容URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求;

5. 区域负载均衡设备会根据用户IP,访问资源以及服务能力为用户选择一台合适的缓存服务器提供服务;

6. 全局负载均衡设备把服务器的IP地址返回给用户;

7. 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,那么这台服务器就向网站的源服务器请求内容,源服务器返回内容给缓存服务器,并根据用户自定义的缓存策略判断是否进行缓存,并返回给用户。

对于程序员而言,需要了解哪些资源比较适合使用CDN进行加速呢?

我们都知道,一个完整的网页资源包括CSS,JS,图片,音频,视频和页面等文件。JS、CSS、图片、音频和视频等都是静态文件,一个成熟的网站在上线过程中对静态文件的变更是比较少的或是不会变更的,这些类型的文件是最适合使用CDN进行加速。通过CDN将这些静态资源分发至全国各地的服务器节点,便可以实现从任何一个地方访问网页都可选择最近的节点服务器进行资源。

页面文件主要分为静态页面文件和动态页面文件。像各大公司的官网首页,退出页面等一般都是静态文件,静态页面文件的结构一般是不会改变的,主要做展示用,这类静态页面文件也很适合做CDN加速。动态页面文件指的是页面会根据服务器端返回的响应内容进行动态渲染,例如JSP,PHP文件等。这些页面文件内容是动态获取的,所以并不适合做CDN加速。因为网页的内容是动态变化的,在服务器端存储的内容有效期是比较短的,这样在浏览器请求到CDN服务器上的内容后会总是以过期来处理,最终还是要向源站服务器发送请求,在这种情况下,CDN的存在就没有意义了。

访问浏览器页面时,我们也可以按F12通过浏览器控制台查看页面资源的一些缓存配置。比如通过谷歌浏览器访问百度网站(baidu),打开控制台可以查看到页面加载过程中请求的资源。选择一个图片资源并查看对应的头部消息,如下图所示:

返回消息中与缓存相关的字段有:Cache-Control、Etag、Expires、Last-Modifie、Pragma等,在这里一一做解释。

Expires: Sun, 03 Nov 2019 09:04:35 GMT;Expires为缓存过期时间配置,如果响应报文中设置了Expires,在Expires过期之前,就可以避免和服务器之间的连接。此时,浏览器无需向浏览器发出请求,只需要自己判断手中的材料是否过期就可以了,完全不需要增加服务器的负担。

Cache-Control: max-age=0;Cache-Control为缓存控制,Cache-Control除了在响应中使用,在请求中也可以使用。控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了哪种缓存方式。Cache-Control常使用no-cache,no-store,max-age=delta-seconds等配置类型;no-cache为告知(代理)服务器不直接使用缓存,要求向源服务器发起请求。no-store为所有的内容都不会缓存,max-age为告知服务器希望接收一个存在时间不大于delta-seconds秒的配置资源。

Last-Modified: Mon, 10 Jun 2019 09:12:15 GMT;Last-Modified为当前文件版本的上一次修改时间,服务器为了通知浏览器当前文件的版本,会发送一个上次修改时间的标签,这样浏览器就知道他收到的这个文件创建时间。

Etag: \”2046392041\”;对应实体内容的一个实体标签,与实体内容紧密相关,实体内容发生任何改变都会使值发生变化。ETag是一个文件的唯一标志符,就像一个哈希或者指纹,每个文件都有一个单独的标志,只要这个文件发生了改变,这个标志就会发生变化。主要为了解决 Last-Modified 无法解决的一些问题。比如一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望认为这个文件被修改了,而重新请求;或者某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒),以及某些服务器不能精确的得到文件的最后修改时间等;

Pragma: no-cache;Pragma的值为no-cache时,表示禁用缓存;Pragma是旧产物,已经逐步抛弃,有些网站为了向下兼容还保留了这两个字段。如果一个报文中同时出现Pragma和Cache-Control时,以Pragma为准。同时出现Cache-Control和Expires时,以Cache-Control为准。即优先级从高到低是 Pragma -> Cache-Control -> Expires。

当不使用CDN的时候,用户在访问网站的时候,浏览器将网站中的图片和静态资源文件保存到本地,这样用户再次访问该网站的时候,浏览器就不用再全部的文件,减少了量,从而提高了页面加载的速度。使用CDN后,将浏览器访问服务器的中间增加一层CDN,浏览器访问服务器时先检查是否有本地缓存是否过期,如果过期,则向CDN边缘节点发起请求,CDN边缘节点会检测用户请求数据的缓存是否过期,如果没有过期,则直接响应用户请求;如果数据已经过期,那么CDN还需要向源站发出回源请求,来拉取最新的数据。

浏览器缓存内容中有Expires或者Cache-Control设置了max-age响应头的时候,浏览器就不会向服务器发起校验请求,而是直接复用本地缓存。如果此时服务器进行了资源的更新,用户就无法获取到最新的资源,只能通过强制刷新浏览器缓存来跟服务器请求最新的资源。使用CDN缓存可以避免浏览器缓存资源更新延迟的现象。CDN缓存不仅可以减少用户的访问延时,而且可以减少源服务器的负载,但需要注意的是,当源服务器资源更新后,如果CDN节点上缓存数据还未同步,用户访问到的依旧是过期的缓存资源,这会导致用户最终访问出现偏差。此时需要手动刷新相关资源,使CDN缓存保持为最新的状态。

浏览器以最少的请求来获取网页的数据,并对所有没有过期的内容直接使用本地缓存,从而减少了对服务器的请求。使用CDN技术,最大的好处就是加速了网站的访问速度,使用户与内容之间的物理距离缩短,以及用户的等待时间缩短,从而提高用户的体验。

作者:曾建,目前就职于苏宁易购,专注于CDN相关系统开发。

声明:本文系作者独立观点,不代表CSDN立场。

【End】

别说你会DIY电脑 主板BIOS更新进阶教程

如同手机ROM刷机、路由器第三方固件,主板的BIOS更新可以带来新功能、新的 CPU支持、重大Bug的修复等等,这个时候就需要动动手更新主板BIOS,目前来看各大主板厂商提供的BIOS更新方式都非常齐全,从DOS到BIOS 再到Windows应有尽有,不过对于很多初阶用户来说这依然是一件麻烦的事儿,另外对于一些MOD BIOS或者刷新过程中损坏的BIOS又该如何刷新呢?下面就跟随笔者一起来学习主板BIOS的更新教程。

什么是主板BIOS?

BIOS基本输入输出系统(Basic Input & Output System)的简称。所谓基本输入输出系统,就是正常启动计算机所必须的条件, 主板BIOS提供了操作系统引导前的POST环境支持。启动计算机时,CPU首先要根据集成在主板、显卡等设备上的BIOS芯片来核对每个基础设备是否正 常,然后再进行下一步程序。依据功能来划分主板BIOS(以Intel BIOS为例)主要包括Descriptor Region、 GbE Region、Intel ME、BIOS Region四个区域,Descriptor Region是BIOS的描述文 件,GbE Region为网卡的固件区域、Intel ME为Intel管理引擎固件区域,而BIOS Region只是其中的一部分,另外有些主板的 BIOS还集成了PDR Region、CBE Region区域等。

当然对于正常的主板BIOS过程来说,一般更新的只有BIOS区域,其它区域一般是锁死的,例如Intel ME区域,一般来说新上一代主板要支持新的CPU,那么Intel ME就需要被更新,但是常规的BIOS区域更新,这篇区域一直被写保护无法更新。

BIOS文件的各部分组成

以 Intel 100系列ME为例,又分为两大类:消费级和商用,消费级包括Z170、H170、B150、H110,商用系列仅包括Q170和 Q150,Intel为消费级主板配备的ME空间只有2MB左右,而商用主板一般在5MB左右。现如今只有Intel只提供Q170、Q150支持 Xeon E3-1200 V5系列处理器就是通过ME区域锁死的。

BIOS刷新方式有哪些?

BIOS 刷新的方式主要包括DOS、BIOS程式、Windows/Linux等操作系统环境三类,在刷新BIOS的过程中,无论是DOS、BIOS程式还是 Windows/Linux等操作系统环境,过程基本相同,都是先校验BIOS文件,然后擦除BIOS文件,再写入BIOS文件,最后校验写入的BIOS 文件是否正确,至此整个BIOS更新过程才算完毕。正是基于这些严格的措施,所以BIOS的刷新基本上停留在厂商推出的正式更新文件,留给MOD或者第三 方更新的空间并不大,不过诸如华硕USB BIOS Flashback等BIOS更新方式也为MOD BIOS开放了一定空间,此前我们在《满满的热 泪 Intel Z87破解硬上NVMe SSD》一文中就使用了这种更新方式将NVMe模块插入到BIOS然后硬上NVMe SSD得以成功。

当 然BIOS还有更原始的更新方法,在主板的制造工厂,BIOS可不是通过诸如DOS、BIOS程式还是Windows/Linux等方式写入的,而是直接 使用烧录器,这种方式首先可以批量写入BIOS文件,另外烧录器还不受系统平台保护的限制,可以将MOD后的BIOS文件直接刷入,另外一些刷新过程中断 的BIOS也可以通过这种方式恢复。

BIOS芯片到底是个什么东东?

主 板使用的BIOS芯片依赖SPI通讯,BIOS文件都是由该通道写入到BIOS芯片当中。主板BIOS芯片为25 SPI FLASH系列,一般采用 DIP-8直插封装或者SOP-8贴片封装,DIP-8直插封装顾名思义就是芯片通过插针直接插入主板的插槽内,可以随时插拔取出,而SOP-8贴片封装 则是通过锡焊接在主板上,无法自由更换。主流的主板如华硕、华擎一般采用了DIP-8直插封装,而技嘉、微星一般都采用了SOP-8贴片封装,焊接在主板 上。

DIP-8直插封装BIOS芯片

SOP-8贴片封装BIOS芯片

无论是DIP-8直插封装还是SOP-8贴片封装,都采用了8个引脚,芯片的左下角为第一引脚,而左上角为第八个引脚。BIOS芯片的主流容量一般为32Mb、64Mb、128Mb,对应的BIOS文件大小分别为4MB、8MB、16MB。

烧录器如何烧录BIOS流程(华硕、技嘉、华擎、微星)?

对于硬件厂商以及大规模的BIOS芯片烧录,显然不是将每块主板启动至系统烧录,那样效率太低,而且对于已经刷死的BIOS,主板是无法启动的,这就需要用到ROM烧录器,ROM烧录器的规格有很多种,主板的芯片类型一般为25 SPI FLASH系列。

烧录器分为脱机烧录和系统烧录,脱机烧录的主要用于批量BIOS芯片的烧录,只需使用一枚已经烧录好的BIOS芯片作为母本或者SD BIOS拷贝,就可以批量复制。

系统烧录一般针对消费级用户,上面已经介绍了主板BIOS分为两大类,DIP-8直插封装可以直接取出安装在烧录器插槽上直接烧录,诸如华硕、华擎主板都采用了DIP-8直插封装BIOS芯片。

SOP-8贴片芯片插槽

对于技嘉主板一般采用了双BIOS设计,而且为SOP-8贴片封装,这个时候就需要用到SOP-8芯片烧录夹夹住M BIOS芯片,然后用线缆连接至烧录器烧录。

DIP-8直插封装BIOS芯片插槽

微星主板虽然也采用了SOP-8贴片封装BIOS芯片,不过微星专门为主板开发了JSPI1接口,这个接口简而言之就是BIOS芯片直连引出的针脚,只要用线缆将接口和烧录器连接起来就可以实现BIOS的刷新操作。

1 2 3 4 5 下一页

更多阅读:

北信源定增15亿项目Linkdood面世 进军IM市场

索尼成立了一家手游公司 这是要干掉任天堂?

双飞燕发光轴2代机械键盘 触发快增加段落感

OPPO R9首日销量超18万台 线下渠道又建功了

JSP的基本使用总结

  1. JSP的全称是Java Server Pages,即Java的服务器页面
  2. JSP的主要作用是代替Servlet程序回传HTML页面的数据
  3. web目录(或其他)右击 –> new –> JSP/JSPX –> 输入文件名 –> 选择JSP file创建

JSP页面本质上是一个Servlet程序,第一次访问JSP页面时(运行Tomcat服务器后在浏览器地址栏输入路径),Tomcat服务器会将此JSP页面翻译成为一个Java源文件,并对其进行编译成为.class字节码文件(一个.java,一个.class),当打开.java文件时发现其中的内容是:

而HttpJspBase类直接继承于HttpServlet类,即JSP翻译出来的Java类间接继承于HttpServlet类,证明JSP页面是一个Servlet程序

JSP头部的page指令:

JSP头部的page指令可以修改JSP页面中的一些重要属性或行为

(以下属性均写在page指令中,默认page指令中没有出现的属性都采用默认值):

(1) contentType属性:表示JSP返回的数据类型是什么,即response.setContentType()的参数值

(2) language属性:表示JSP翻译之后是什么语言文件(目前只支持Java)

(3) pageEncoding属性:表示当前JSP文件本身的字符集(可在IDEA右下角看到)

(4) import属性:表示导包(导类),与Java一致

(5) autoFlush属性:设置当out输出流缓冲区满了之后是否自动刷新缓冲区,默认值是true

(6) buffer属性:设置out缓冲区的大小,默认是8kb

注意:out缓冲区满了之后不能自动刷新的话会报错

(7) errorPage属性:设置当JSP页面运行出错时自动跳转到的页面(错误信息页面)的路径,这个 路径一般都是以斜杠打头,表示请求的地址是http://ip:port/工程路径/,对应代码web目录

(8) isErrorPage属性:设置当前JSP页面是否是错误信息页面,默认是false,如果是true可以 获取错误信息

(9) session属性:设置访问当前JSP页面时是否会创建HttpSession对象,默认值是true

(10) extends属性:设置JSP页面翻译出来的Java类默认继承谁

注意:以上默认值除非有特殊需要,否则不建议修改

格式:<%! 声明Java代码 %>

作用:可以给JSP翻译出来的Java类定义属性、方法、静态代码块、内部类等

特点:不会在浏览器的页面上显示出来,仅存在于翻译后的Java类中

代码演示:声明脚本的使用(此JSP文件在web目录下,名为First.jsp)

%@ page contentType=\”text/html;charset=UTF-8\” language=\”java\” %>

<%@ page import=\”java.util.HashMap\” %>

<%@ page import=\”java.util.Map\” %>

<html>

<head>

<title>Title</title>

</head>

<body>

<%–1.声明类属性–%>

<%!

private String name;

private static Map<String, Object> map;

%>

<%–2.声明类方法–%>

<%!

public int sum() {

return 12;

}

%>

<%–3.声明静态代码块–%>

<%!

static {

map = new HashMap<String, Object>();

map.put(\”key1\”, \”value1\”);

}

%>

</body>

</html>

对应的翻译后的java源文件:

格式:<%=表达式 %>

作用:在浏览器的JSP页面上输出数据(只有此脚本可以在浏览器的页面上输出数据)

特点:

(1) 所有的表达式脚本都会被翻译到对应的Java类的_jspService()方法中,故表达式脚本可以 直接使用_jspService()方法参数中的对象

(2) 表达式脚本都会被编译后的Java类中的out.print()方法输出到浏览器页面上

(3) 表达式脚本中的表达式不能以分号结束

代码演示:表达式脚本的使用(此JSP文件在web目录下,名为First.jsp)

<%=22 %> <br/>

<%=\”可以输出字符串\” %> <br/>

<%=map %> <br/>

<%–使用_jspService方法中的对象–%>

<%=request.getParameter(\”username\”) %>

启动Tomcat服务器后浏览器的运行结果:

对应的翻译后的Java源文件(在_jspService方法中):

注意:

1.write方法中的标签、转义字符自动识别为对应的

功能,不在页面输出,执行各自代表的功能

2.out的两个方法也在_jspService方法中,也都是java语言

3.只有print、write方法、表达式脚本中的内容才可在浏览器中显示,其余Java代码的sout在控制台输出

格式:<% Java语句 %>

作用:在JSP页面中可以编写需要的Java代码

特点:

(1) 代码脚本翻译后都在_jspService方法中,故代码脚本可以直接使用此方法参数中的对象

(2) 可以由多个代码脚本块组合完成一个完整的Java语句

(3) 代码脚本还可以和表达式脚本一起组合使用,在JSP页面上输出数据

代码演示:代码脚本的使用(此JSP文件在web目录下,名为First.jsp)

<%–1.if语句–%>

<%

int i = 1;

if (i == 1) {

System.out.println(\”我爱祖国!\”);

} else {

System.out.println(\”我很爱祖国!\”);

}

%> <br/>

<%–2.for循环语句–%>

<%

for (int j = 0 ; j < 3; j++) {

System.out.println(\”第\” + j + \”次循环\”);

}

%> <br/>

<%–3.使用_jspService方法参数中的对象–%>

<%

String username = request.getParameter(\”username\”);

System.out.println(\”username对应的值为:\” + username);

%>

运行结果:

启动Tomcat服务器后在地址栏输入:http://localhost:8080/MyTest/First.jsp?username=Jaychou

在控制台显示:

对应的翻译后的Java源文件(在_jspService方法中):

1.HTML注释:<!–HTML注释–>

HTML注释会被翻译到JSP文件对应的Java类的_jspService方法中,以out.write()输出到客户端,

write方法会自动识别标签,执行标签对应的功能,不会在浏览器的页面上输出注释

2.Java注释:(1) //单行注释 (2) /*多行注释*/

Java注释要写在声明脚本和代码脚本中才被认为是Java注释,会被翻译到JSP文件对应的Java类的_jspService方法中,在对应的Java类中也是注释

3.JSP注释:<%- -这是JSP注释- -%>

JSP注释中的内容不会在JSP文件翻译后的Java类中出现,即注释中的内容没有任何功能

JSP的内置对象指的是Tomcat服务器将JSP页面翻译为Java类之后内部提供的九大对象:

(将page指令的isErrorPage属性写成true可以出现exception对象)

request:请求对象

response:响应对象

pageContext:JSP的上下文对象

session:会话对象

application:ServletContext对象

config:ServletConfig对象

out:JSP输出流对象

page:指向当前JSP的对象

exception:异常对象

域对象是指可以像Map一样存取数据的对象,四个域对象功能一样,只是对数据的存取范围不同

代码演示1:四个域对象存取数据的范围的不同(在web目录下创建scope1.jsp)

<%@ page contentType=\”text/html;charset=UTF-8\” language=\”java\” %>

<html>

<head>

<title>scope1</title>

</head>

<body>

<h1>scope1.jsp页面</h1>

<%

//向四个域对象中分别保存数据

pageContext.setAttribute(\”key\”, \”pageContext\”);

request.setAttribute(\”key\”, \”request\”);

session.setAttribute(\”key\”, \”session\”);

application.setAttribute(\”key\”, \”application\”);

%>

<%– <jsp:forward page=\”\”></jsp:forward>是请求转发标签,

page属性设置请求转发的路径 –%>

<jsp:forward page=\”/scope2.jsp\”></jsp:forward>

</body>

代码演示2:在web目录下创建scope2.jsp

<head>

<title>Title</title>

</head>

<body>

<h1>scope2.jsp页面</h1>

<%– JSP页面中不加任何标签直接输入的内容被write方法输出在浏览器的页面上 –%>

pageContext域是否有值:<%=pageContext.getAttribute(\”key\”)%> <br>

request域是否有值:<%=request.getAttribute(\”key\”)%> <br>

session域是否有值:<%=session.getAttribute(\”key\”)%> <br>

application域是否有值:<%=application.getAttribute(\”key\”)%> <br>

</body>

运行结果1:

运行结果2:

注意:若四个域对象在使用时范围都可满足要求,则使用的优先顺序是(范围从小到大):

pageContext –> request –> session –> application

1.相同点:response表示响应,用于给客户端(浏览器)返回内容

out同样也是用于给客户端(浏览器)输出内容

2.不同点:

3.注意:由于官方的代码中翻译后的Java代码底层都是使用out进行输出,故一般都使用out进行 输出,out又分为write方法和print方法:

(1) out.print():会将任何内容转换成字符串后调用write方法输出

(2) out.write():输出字符串没有问题,但输出int型时会将int转换成char输出,导致输出的并非是想要的数字而是数字对应的ASCII码

结论:JSP页面的代码脚本中任何要输出在浏览器的内容均使用out.print()方法

(1)使用场景:

(2)使用方法:

<%@include file=\”\”%>

其中file属性设置要包含的JSP页面,以/打头,代表http://ip:port/工程路径/,对应web目录

代码演示1:在web目录下创建body.jsp

<body>

头部信息 <br>

主体信息 <br>

<%@include file=\”/foot.jsp\”%>

</body>

代码演示2:在web目录下创建foot.jsp

<body>

页脚信息 <br>

</body>

运行结果:

(3)静态包含的特点:

①静态包含不会将被包含的JSP页面翻译成.java.class文件

②静态包含是把被包含的页面的代码拷贝到body.jsp对应的Java文件的对应位置执行输出

(1)使用方法:

<jsp:include page=””></jsp:include>

其中page属性设置要包含的JSP页面,与静态包含一致

(2)动态包含的特点:

①动态包含将被包含的JSP页面翻译成.java.class文件

②动态包含还可以传递参数

③动态包含底层使用如下代码调用被包含的JSP页面执行输出:

org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/foot.jsp”, out, false);

代码演示1:在web目录下创建body.jsp

<body>

头部信息 <br>

主体信息 <br>

<jsp:include page=\”/foot.jsp\”>

<jsp:param name=\”username\” value=\”Jaychou\”/>

<jsp:param name=\”password\” value=\”root\”/>

</jsp:include>

</body>

注意:

  1. 设置参数的标签要写在动态包含之中
  2. 出现Expecting “jsp:param” standard action with “name” and “value” attributes异常,两个原因:

①动态包含中未设置参数但没有把<jsp:include page=””></jsp:include>放在一行上

②动态包含中加了注释

代码演示2:在web目录下创建foot.jsp

<body>

页脚信息 <br>

<%=request.getParameter(\”username\”)%>

</body>

运行结果:

(3)动态包含的底层原理:

(1) Listener监听器是JavaWeb的三大组件之一

(2) Listener监听器是JavaEE的规范(接口)

(3) Listener监听器的作用是监听某件事物的变化,然后通过回调函数反馈给程序做一些处理

ServletContextListener监听器可以监听ServletContext对象的创建和销毁(web工程启动时创建,停止时销毁),监听到创建和销毁之后都会调用ServletContextListener监听器的方法进行反馈:

public interface ServletContextListener extends EventListener {

//在ServletContext对象创建之后调用

public void contextInitialized(ServletContextEvent sce);

//在ServletContext对象销毁之后调用

public void contextDestroyed(ServletContextEvent sce);

}

(1) 编写一个类实现ServletContextListener接口

(2) 重写两个方法

(3) 在web.xml文件中配置监听器

代码演示1:创建一个类

ublic class ListenerTest implements ServletContextListener {

@Override

public void contextInitialized(ServletContextEvent servletContextEvent) {

System.out.println(\”ServletContext对象创建\”);

}

@Override

public void contextDestroyed(ServletContextEvent servletContextEvent) {

System.out.println(\”ServletContext对象销毁\”);

}

}

代码演示2:在web.xml中配置

<listener>

<!– <listener-class>标签中写上述程序的全类名 –>

<listener-class>com.qizegao.servlet.ListenerTest</listener-class>

</listener>

运行结果:

Tomcat服务器启动之后控制台输出ServletContext对象创建

Tomcat服务器停止之后控制台输出ServletContext对象销毁

注意:

  1. 查看翻译后的Java源文件的方法:启动Tomcat服务器访问到JSP页面之后在控制台输出的信息的前端找到Using CATALINA_BASE中的路径,在硬盘中打开此目录,点击work –> Catalina –> localhost,找到对应的工程文件夹寻找即可
  2. 访问JSP页面其实是在执行对应的翻译后的Java代码的_jspService方法:翻译后的Java类中没有service方法,而是重写了父类的_jspService方法,这个方法会被父类的service方法调用

[机智]

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。