Servlet的继承树,生命周期和线程不安全

1、Servlet 继承树

java 复制代码
3)Servlet的继承树
- Servlet接口
   public interface Servlet{
       public void init(config);
       public void service(request,response);
       public void destroy();
   }
- GenericServlet抽象类
   public abstract class GenericServlet implements Servlet{
       实现了init方法和destroy方法。service方法仍然保持抽象
   }
- HttpServlet抽象类 - 最初设计时,基于http协议,因此产生了HttpServlet,将来可能会基于其他协议出现其他协议下的Servlet
   public abstract class HttpServlet extends GenericServlet{
        实现了service方法。然后重载了service方法
        protected void service(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{
            String method=request.getMethod();
            if("POST".equals(method)){
                doPost(request,response);
            }else if("PUT".equals(method)){
                doPut(...)
            }else{...
            }
        }
        细化了服务方法:
        public void doPost(){}
        public void doGet(){}
        public void doDelete(){}
        public void doPut(){}
   }

2、Servlet 生命周期

XML 复制代码
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.csdn</groupId>
            <artifactId>pro03-fruit-optimize</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
java 复制代码
package com.csdn.servlet;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;
//4、演示Servlet生命周期
@WebServlet("/h04")
public class ServletLifecycle extends GenericServlet {
    // tomcat被执行的时候,他是不会被实例化的,这样是比较合理的
    // 因为假设项目里面有一万个Servlet,tomcat在启动的时候,
    // 就要实例化一万个实例对象,但是一万个也不知道用户什么时候来访问,
    // 放在tomcat里面,就会使tomcat启动的时间拉长,延迟实例化,只执行一次
    public ServletLifecycle() {
        System.out.println("ServletLifecycle正在实例化....");
    }
    //当有请求到来时,会被执行,多次请求可以执行多次
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("ServletLifecycle正在服务....");
    }
    //请求到来时,先实例化,然后执行init方法,只执行一次,然后执行service方法
    @Override
    public void init() throws ServletException {
        System.out.println("ServletLifecycle正在初始化....");

    }
    //tomcat停止时,执行destroy方法
    @Override
    public void destroy() {
        System.out.println("ServletLifecycle正在销毁....");
    }
}
java 复制代码
4)Servlet的生命周期
- Servlet是tomcat去实例化的,不是程序员new的
- Servlet中的服务方法也不是程序员主动调用的,也是由tomcat去调用的。当有请求到来时,tomcat通过反射执行service方法
- Servlet的生命周期分为四个阶段:实例化、初始化、服务、销毁
- 默认情况下,Servlet不会随着容器的启动而被实例化,而是当第一次有人请求我的时候,我才会被实例化
  当容器停止时,容器中的Servlet实例会被销毁,destroy方法被调用

3、Servlet 线程不安全问题

java 复制代码
package com.csdn.servlet;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;
//5、演示线程不安全的问题
@WebServlet("/h05")
public class ThreadUnsafeServlet extends GenericServlet {
    public Integer i = 1;
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        if (i % 2 == 0) {
            System.out.print("A");
        } else {
            System.out.print("B");
        }
        i++;
    }
}
java 复制代码
- Servlet在tomcat容器中是单实例的是线程不安全的
        ① 单实例的意思是:所有客户端发过来的请求都是同一个ServletLifecycle实例来处理
            第一个用户发请求过来时,容器会去实例化servlet,然后进入服务阶段,从此之后,所有的请求到来时,直接执行服务方法
        ② 线程不安全的意思时:既然所有的请求到来时是同一个servlet实例去处理的,那么这些请求之间不能共用数据(共用变量)
            什么情况下共用变量?servlet中有成员变量,而服务方法中需要根据成员变量的值决定程序流程
            如果第一个请求到来时,执行服务方法,然后在服务方法中更改成员的值,从而就会导致其他的请求到来时流程发生变化
            小结:线程不安全的本质是:Servlet由成员变量;成员变量的值可能发生变化;业务逻辑依赖于这个变量
        ③ 如何解决线程不安全的问题:尽量避免使用成员变量;如果非要使用成员变量,那么要注意业务逻辑不要受成员变量值影响
相关推荐
我命由我123455 小时前
Android Studio - Android Studio 自定义预览尺寸
android·java·ide·java-ee·android studio·android-studio·android runtime
咖啡八杯6 小时前
GoF设计模式——迭代器模式
java·后端·设计模式·迭代器模式
AIGS0016 小时前
企业AI落地的关键认知:向量空间JBoltAI的本体语义平台
java·人工智能·人工智能ai大模型应用
KaMeidebaby7 小时前
卡梅德生物技术快报|抗体亲和力成熟工业化调控新机制:差异性浆细胞增殖工艺优化思路
java·开发语言·人工智能·算法·机器学习·架构·spark
醉城夜风~9 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法
数智化转型推荐官10 小时前
2026统一身份管理系统五大发展趋势解读
java·运维·微服务
看菜鸡互10 小时前
探索用 SlideML 让大模型生成 PPT 的实验方法
java·运维
程序员张312 小时前
SpringBoot集成BCrypt密码加密库
java·spring boot·后端
闲猫12 小时前
Spring AI Agentic 模式(第1部分):Agent Skills——模块化、可复用的能力
java·人工智能·spring
源图客12 小时前
云途物流API开发-鉴权认证(Java)
java·网络·python