关于Servlet的学习总结和一小点心得(1)

本文分享了Servlet的学习收获。Servlet是沟通服务器和Java程序的桥梁,是Java接口。以Tomcat服务器为例,介绍了Servlet对象的生命周期、线程安全问题。还探讨了Servlet中各方法的编写时机,以及ServletConfig、ServletContext接口,分析了它们与Servlet之间的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这些天自己学习了一下Servlet,有一些收获,写一个博客复习一下,同时分享给大家

首先我们需要了解一下什么是Servlet?

servlet在我看来是用来沟通服务器和java程序的桥梁。用户首先在浏览器上向服务器发出请求,服务器接受到请求之后通过servlet里面的doget或者dopost方法进行处理,处理结果提交给服务器,同时服务器对请求的浏览器发出响应。

而Servlet是一个java的接口,我们通过实现这个接口从而在web服务器那里实现功能

假设我们与后端交互的服务器是Tomcat服务器,那么一个servlet对象的生命周期是:

  1. 当用户在地址栏输入url: http://localhost:8080/
  2. web容器截取请求路径,并且在容器上下文中找请求路径
  3. 如果没有找到对应的Servlet对象咋么办?(实际服务器启动的时候就已经把web.xml文件解析好了,放入map中)
    通过web.xml文件中相关的配置信息,得到请求 通过反射机制调用servlet类的无参数构造方法,完成Servlet类的实例化
    web容器调用servlet对象的init方法完成初始化操作
    web容器调用Servlet对象的方法提供服务
  1. 若找到对应的Servlet对象web容器直接调用servlet对象的service方法提供服务
  2. web容器关闭的时候/webapp重新部署的时候/该Servlet对象长时间不访问的时候 web容器会将该servlet对象销毁,在销毁该对象之前web容器调用destory方法销毁

我们可以总结一下:

  1. Servlet类的构造方法只执行一次
  2. Servlet对象的init方法值只执行一次
  3. Servlet对象的service方法,只要用户请求一次,则执行一次
  4. Servlet对象的destory方法只执行一次

注意重点:

service方法是只要用户请求一次就执行一次的
init方法执行的时候,Servlet对象已经创建好了
destroy方法执行的时候,Servlet对象还没有被销毁,即将被销毁
Servlet对象是单例,但是不符合单例模式,只能称为伪单例。
真单例的构造方法是私有化的,Tomcat服务器是支持多线程的
所以Servlet对象在单实例多线程的环境下运行的
那么servlet对象中若有实例变量,并且实例变量涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题
不建议在Servlet对象中使用实例变量,尽量使用局部变量

那么问题来了--------------------->Servlet对象实例化后,这个对象存到哪里了?
大多数WEB容器都是将该Servlet对象以及对应的url-pattern存储到map集合中:
WEB容器中有这样一个MAP集合
Map<String,Servlet>

key                 value
-------------------------------
/login              LoginServlet对象引用
/delate             DelateServlet对象引用
/save               SaveServlet对象引用

服务器在启动的时候就会解析各个Webapp的web.xml文件,所以需要把配置文件中的类的名字和对应的路径放到某一个集合中

将web.xml中的url-pattern 和对应类名存储到map中:

Map<String,String>

key                 value
-------------------------------
/login             com.anine.test.LoginServlet
.......

下面我们研究一下servlet中的几个方法什么时候编写什么代码:

  1. 无参数的构造方法[尽量别动构造函数] :创建对象之后执行的

  2. init方法
    -----------以上两个方法,执行时间几乎相同,执行次数都是一次*****-----------------
    其实尽量别在构造方法里面写东西,尽量把对象创建时刻要写的方法写在init中
    因为写在构造函数中存在风险 :当程序员编写构造方法的时候,可能会导致无参数的构造方法不存在
    比如突然写了一个有参数的构造方法

    init是SUN公司为javaweb程序员专门提供的初始化时刻,若希望在初始化时刻执行一段特殊的程序,这个程序可以编写到init方法中

  3. service 方法
    必然要重写的,因为需要完成业务所及的处理,请求的处理,以及完成响应,
    而且这个方法中的代码最有价值
    也是最难写的。

  4. 这个方法是SUN公司为javaweb程序员提供的一个特殊时刻,这个特殊时刻被称为对象的销毁时刻
    若希望在销毁时刻执行一段特殊的代码,需要将这段代码编写到destory方法,自动被容器调用

下面我们了解一下ServletConfig接口
我们可以创建两个Servlet对象产生一下对应的ServletConfig接口对象

AServlet’s ServletConfig is org.apache.catalina.core.StandardWrapperFacade@49ab9c7d
BServlet’s ServletConfig is org.apache.catalina.core.StandardWrapperFacade@2c8a75d0

我们可以观察出,不同的Servlet对象拥有不同的ServletConfig对象
插一句嘴:
其实我们一直在面向接口编程

  1. javax.servlet.ServletConfig是接口

  2. Apache Tomcat服务器实现了servlet规范,Tomcat服务器专门写了一个ServletConfig接口的实现类
    实现的类名org.apache.catalina.core.StandardWrapperFacade

  3. 面向这个ServletConfig接口编程的
    WEB容器实现了接口,我们可以调用

  4. 同学!Tomcat服务器你怎么理解?
    Tomcat服务器是一个实现了Servlet规范和JSP规范的容器

  5. 研究ServletConfig接口都有啥方法

    -String getInitParameter(String name); 获取所有初始化参数的名字
    -Enumeration getInitParameterNames(); 返回一堆东西,应该是集合
    -String getServletContext();获取ServletName <servlet-name>b</servlet-name>
    -String getServletName();获取Servlet上下文
    

好了,我们继续研究ServletConfig到底是个啥?

ServletConfig是一个Servlet对象的适配信息对象,ServletConfig对象中封装了一个servlet对象的配置信息。
Servlet对象的配置信息在web.xml文件中。
web.xml的配置信息封装到了ServletConfig中
因为一个Servlet对应一个标签,所以内存地址是不一样的

一个Servlet对象对应一个servletConfig对象。

我们再来看一下ServletContext是一个什么接口?
还是举一个例子:假设有两个Servlet对象

AServletContext is org.apache.catalina.core.ApplicationContextFacade@43df86ff
BServletContext is org.apache.catalina.core.ApplicationContextFacade@43df86ff

我们可以进一步总结出,所有的Servlet对象共享一个ServletContext

ServletContext到底是什么?什么时候被创建?什么时候被销毁?

ServletContext被翻译为:Servlet上下文
一个WEBAPP只有一个ServletContext对象
一个WEBAPP只有一个web.xml文件
web.xml在服务器启动的时候被解析
ServletContext在服务器启动阶段实例化
ServletContext在服务器关闭阶段被销毁
ServletContext对应的是web.xml文件,是web.xml文件的代表
还有人说ServletContex是所有Servlet对象四周的环境代表

.ServletContext接口中有哪些方法?

	- void setAttribute(String name,Object object);//向ServletContext范围中绑定数据map.put(key,value)
	- Object getAttribute(String name);//从ServletContext范围中获取数据map.get(key)
	- void removeAttributes(String name);//移除ServletContext范围中的数据map.remove(key)
	- String getInitParamter(String name);
	- Enumeration getInitParamterNames();
	- String getRealPath(String path);
	//获取文件绝对路径

最后的最后,我们来研究一下Servlet、ServletConfig、ServletContext之间的关系?

	-- 一个Servlet对应一个ServletConfig
	-- 100个Servlet对应100个servletConfig
	--所有的Servlet共享一个ServletContext对象[在同一个webapp中,所有的Servlet对象共享同一个四周环境对象,该对象就是ServletContext]
	所有用户若想共享同一个数据,可以将这个数据放到ServletContext对象中。
	一般放到ServletContext中的数据,是不建议涉及到修改操作的,因为ServletContext是多线程共享的对象,修改的时候会存在线程安全问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值