【Servlet】Servlet的生命周期

目录

一、Servlet的生命周期

二、Servlet的生命周期演示图 

三、线程安全问题

四、解决线程安全问题

五、HttpServletRequest的一些核心方法


面试题

一、Servlet的生命周期

1.类加载和实例化

Servlet容器(如Tomcat)负责加载和实例化Servlet。当容器是首次启动或首次请求某个Servlet时,容器就会读取web.xml或@WebServlet中的配置信息,对指定的Servlet进行加载。加载成功后,容器会通过反射对Servlet进行实例化,这里反射的本质就是调用Servlet的无参构造方法。容器会调用ServletContext的getServlet方法来获取Servlet实例。

Tomcat 的代码中内置了 main 方法 . 当我们启动 Tomcat 的时候 , 就是从 Tomcat main 方法开
始执行的,被 @WebServlet 注解修饰的类会在 Tomcat 启动的时候就被获取到 , 并集中管理。Tomcat 通过  反射  这样的语法机制来创建被 @WebServlet 注解修饰的类的实例。Tomcat 内部也是通过 Socket API 进行网络通信。

2.初始化

Servlet实例化之后,Servlet容器调用Servlet的init()方法,初始化的目的是为了让Servlet在处理请求之前完成一些初始化的工作,比如建立与数据库的连接,获取配置信息等。在servlet的整个生命周期内,该方法只会被执行这一次。

3.就绪状态

当Servlet完成初始化后,容器就会将它放入就绪状态,表示它已经准备好处理客户端请求了。

3.客户端发送一个请求,Servlet容器解析并处理请求

当客户端发起请求时,Servlet容器会为每个请求创建一个新的线程,并且调用Servlet的service()方法处理请求。当Servlet容器接收到来自客户端的请求时,容器会针对该请求分别创建一个ServletRequest对象和ServletResponse对象,并将他们以参数的形式传入service()方法内,后续通过调用该方法处理请求。在service()方法中,Servlet通过ServletRequest对象获取客户端的相关信息和请求信息。请求处理完后,又通过ServletResponse对象将响应信息进行包装返回给客户端。当Servlet容器将响应信息返回给客户端后,这两个对象就会被销毁,即这两个对象的生命周期是单次请求内。在Servlet的整个生命周期内,对于Servlet的每一次请求,Servlet容器都会调用一次service()方法,并创建新的ServletRequest和ServletResponse对象。Tomcat(Servlet容器) 从 Socket 中读到的 HTTP 请求是一个字符串, 然后会按照 HTTP 协议的格式解析成一个

HttpServletRequest 对象。

       

4.销毁阶段

当Servlet容器关闭或重启时,servlet的生命周期结束。容器就会调用destory()方法,释放该实例Servlet使用的资源,如关闭数据库连接、保存会话数据等。随后该实例会被Java的垃圾回收器回收。在Servlet的整个生命周期内,该方法只被调用一次。

二、Servlet的生命周期演示图 

【Servlet】Servlet的生命周期_第1张图片

【Servlet】Servlet的生命周期_第2张图片

三、线程安全问题

Servlet是线程不安全的,通过Servlet的生命周期发现,它是个单例模式。正是因为单例模式才更应该要考虑线程安全问题。当每个用户请求时,都会为他们创建一个新的线程。即单实例多线程。优点是,缺点是存在线程安全问题。比如Servlet代码逻辑中有去全局变量。多线程下所有线程共享实例变量。出现临界值,就会引发线程安全问题。

四、解决线程安全问题

  1. 不使用实例(全局)变量。事实上,线程安全问题大多是由实例(全局)变量造成的。建议使用。
  2. 使用Synchronized加锁,保证一次只有一个线程可以访问被保护的区段,加锁实际上也是将多线程并发执行变成串行执行了。这样当大量用户访问同一资源时,用户只能排队一个一个访问,就会出现阻塞状态,造成用户的不好体验,不建议使用。

五、HttpServletRequest的一些核心方法

方法
描述
String getProtocol()
返回请求协议的名称和版本。
String getMethod()
返回请求的 HTTP 方法的名称,例如, GET POST PUT
String getRequestURI()
从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请 求的 URL 的一部分。
String getContextPath()
返回指示请求上下文的请求 URI 部分。
String getQueryString()
返回包含在路径后的请求 URL 中的查询字符串。
Enumeration getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名 称。
String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回null。
String[]
getParameterValues(String name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如 果参数不存在则返回NULL
Enumeration getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String name)
以字符串形式返回指定的请求头的值。
String  getCharacterEncoding()
返回请求主体中使用的字符编码的名称。

你可能感兴趣的:(习题总结,多线程安全,servlet)