Tomcat中的Servlet和GenericServlet学习总结

Tomcat中的Servlet和GenericServlet学习总结,第1张

Tomcat中的Servlet和GenericServlet学习总结 Tomcat服务器Servlet底层分析、学习总结

目录

Tomcat服务器Servlet底层分析、学习总结Servlet生命周期GenericServlet抽象类ServletConfigServletContext通过ServletContext对象记录日志:怎么向ServletContext应用域中存数据:

近期看了动力节点老杜的Tomcat讲解,今天做一个总结。回顾一下之前学的知识,同时记录一下,以便之后可以复习回顾。
我们都知道Servlet是JavaEE的规范之一,本质上,它是一个接口。我们可以从帮助文档中看出


其中init方法,service方法,destory方法是和Servlet生命周期相关的(我们着重讲这三个方法)。

Servlet生命周期

一个Servlet创建到销毁主要经历三个方法就是init方法,service方法,destory方法。

用户在发送第一次请求时Servlet对象被实例化。
AServlet对象被创建出来之后,Tomcat服务器马上调用AServlet对象的init方法(init方法执行的时候,AServlet对象已经存在了)

*用户发送第一次请求时,init方法执行之后,Tomcat服务器马上调用AServlet对象的service方法。

*用户发送第二次请求时,只执行service方法。
*第三次,第四次、、、,Servlet对象并没有新建,还是之前创建好的Servlet对象,直接调用Servlet对象的service方法,这说明:
+第一:Servlet对象是单例的(单实例,Servlet对象是单实例的,但是Servlet类并不符合单例模式。我们称之为假单例。Tomcat只创建了一个。真单例模式,构造方法私有化)
+第二:无参数构造方法、init方法只在用户第一次发送请求时调用。
+第三:service方法:用户请求一次调用一次。

*关闭服务器时,调用destory方法 Destory方法什么时候被调用: 服务器关闭时 (因为服务器关闭时要销毁Servlet对象的内存) (服务器在销毁Servlet对象之前,Tomcat服务器会自动调用Servlet的Destory方法)

总结:创建–>初始化–>服务–>销毁

GenericServlet抽象类

这里用到的设计模式为适配器模式。我们举一个例子,手机充电时不能直接连接220V的电源上,要有一个适配器,也就是充电器,帮我们的手机充电,这样可以将220V的电压降到手机可接受的范围。

这里的GenericServlet就是充当一个充电器的角色。我们直接实现Servlet是很不现实的,也是很蠢的。需要有一个类帮我们把一些方法实现,我们再继承这个类只实现其中的一个或两个方法。这样下来,我们只用实现一个方法,工作效率远大于我们要实现接口中的所有方法。这个思路确实很巧妙。开发Tomcat的大佬们确实牛。

接下来我们看GenericSevlet中的方法:


先说重要的:我们可以看到GenericServlet已经把大部分方法已经实现,只剩下一个抽象方法service方法,这个就是我们前面所说的留到子类重要实现的方法(必须要实现)。其余的方法可以重写(非必须)。

但我们注意到其中由两个init方法,一个带参数,一个不带参数,为什么Tomcat要在GenericServlet中多写一个不带参的init方法呢?

我们查看底层源码:

private transient ServletConfig config;
public ServletConfig getServletConfig() {
    return this.config;
}
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

public void init() throws ServletException {
}

很明显,带参的init方法是从Servlet接口中继承的,这里是Servlet的init方法的实现方法。我们设想这样一种场景:将来程序员在编程的时候有没有可能遇到这样的情况:我需要在服务器初始化时就要设置一些东西。初始化时是我们设置东西的时候,而根据java的子类对父类重写时,子类方法会覆盖父类的方法。那就说明GenericServlet中的带参init方法完全成了空气,将来子类覆盖父类方法,父类中的工作就白做了,所以这里Tomcat的开发人员有用一个巧妙的方法能让程序员重写init方法,并且不会影响父类的init方法,就是定义一个无参的init方法,将来程序员只需重写无参的init方法就能在初始化时设置一些参数。

ServletConfig

ServletConfig是servlet规范中的一员,是一个接口;
Servlet对象的配置信息对象。
谁实现了ServletConfig接口:Web服务器
Tomcat服务器实现类:
Public class org.apache.catalina.core.StandardWrapperFacade implements ServleyConfig{}
一个Servlet对象中有一个ServletConfig对象(一对一)
ServletConfig对象是由Tomcat服务器创建的,在创建Servlet对象时,同是就创建了一个ServletConfig对象
ServletConfig对象包含了.xml文件中的的信息
ServletConfig接口中有方法:(获取初始化参数信息)
Public String getInitParameter(String name)------通过初始化参数的name获取value
Public Enumeration getInitParameterName()-----获取所有初始化参数的name
Public ServletContext getServletContext()------获取ServletContext对象
Public String getServletName()-----获取Servlet的name

ServletContext

只要在同一个webapp中,只要在同一个应用当中,所有Servlet对象都共享一个ServletContext对象。
ServletContext对象在服务器启动阶段创建,在服务器关闭时候销毁,这就是ServletConfig对象的生命周期。
Tomcat服务器中有webapps,其中有几个webapp(几个web应用),就有几个ServletConfig对象。
ServletConfig对象通常称为Servlet上下文对象,一个ServletContext对象通常对应一个web.xml文件。
ServletContext是一个接口,Tomcat服务器对ServletContext接口进行实现。
ServletContext接口有哪些常用方法
public String getInitParameter(String name)
Public Enumeration getInitParameterName()

通过ServletContext对象记录日志:

Public void log(String message);
Public void log(String message,Throwable t);
日志信息记到哪了?
Localhost.yyyy-mm-dd.log
ServletContext对象还有另一个名字:应用域
如果所有用户共享一份数据,并且这个数据很少被修改,并且数据量很少,可将这些数据放到ServletContext这个应用域中。
共享数据:不共享没有意义,ServletContext对象只有一个;
数据量小:数据量比较大的话太占用堆内存,并且生命周期比较长
很少修改:所有用户共享,如果修改必然存在线程并发所带来的问题,所以很少修改

怎么向ServletContext应用域中存数据:

Public void serAttribute(String name,Obiect value);
取:
Public Object getAttribute(String name);
删:
Public void removeAttribute(String name);

以后编写Servlet类时,不会直接继承GenericServlet类的,因为B/S结构 ,这种系统是基于HTTP超文本传输协议的,在Servlet规范中,提供了一个类叫做HttpServlet,它是专门为HTTP协议准备了一个Servlet类。我们编写Servlet类要继承HttpServlet(HttpServlet是HTTP协议专用的)使用HttpServlet处理HTTP协议更便捷
*jakarta.servlet.Servlet(接口)【爷爷】
*jakarta.servlet.GenericServlet implements Servlet(抽象类)【儿子】
*jakarta.servlet.http.HttpServlet extends GenericServlet(抽象类)【孙子】

关于HttpSevlet我们以后再说。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5708954.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存