Servlet:访问流程、核心接口与生命周期
深入理解 Servlet访问流程、核心接口与生命周期在 Java Web 开发中Servlet 是基石般的存在。无论是传统的 JSP 还是现代的 Spring MVC底层都离不开 Servlet 的支持。本文将围绕 Servlet 的访问流程、体系结构、生命周期以及两个重要的配置对象ServletConfig 和 ServletContext展开结合流程图与类图帮助大家彻底掌握 Servlet 的核心原理。一、Servlet 访问流程浏览器向 Web 服务器发起请求服务器根据 URL 映射找到对应的 Servlet然后执行一系列操作。整个过程可以用下面的流程图表示自定义ServletServlet容器Web服务器浏览器自定义ServletServlet容器Web服务器浏览器发起HTTP请求解析请求定位Servlet创建HttpServletRequest/HttpServletResponse对象调用service()方法处理请求并返回响应封装响应对象返回HTTP响应关键点在调用service()方法之前容器会自动创建HttpServletRequest和HttpServletResponse对象。service()方法会根据请求类型GET、POST 等分发给对应的doGet()、doPost()方法。响应结束后容器负责将响应数据发送回浏览器。二、Servlet 体系结构UML 类图Servlet 规范中我们通常继承HttpServlet来编写自己的业务逻辑。下图展示了Servlet核心接口与类的继承关系实现继承继承«interface»Servletinit(ServletConfig config)service(ServletRequest req, ServletResponse res)destroy()getServletConfig()getServletInfo()«abstract»GenericServlet-config: ServletConfiginit(ServletConfig config)init()getServletConfig()getServletContext()log(String msg)abstract service(ServletRequest req, ServletResponse res)«abstract»HttpServletservice(ServletRequest req, ServletResponse res)service(HttpServletRequest req, HttpServletResponse resp)doGet(HttpServletRequest req, HttpServletResponse resp)doPost(HttpServletRequest req, HttpServletResponse resp)doPut(...)doDelete(...)MyServletdoGet(HttpServletRequest req, HttpServletResponse resp)doPost(HttpServletRequest req, HttpServletResponse resp)说明Servlet接口定义了所有 Servlet 必须实现的生命周期方法。GenericServlet抽象类提供了Servlet接口的基本实现并增加了日志、初始化参数等辅助方法但依然保留了service()方法为抽象。HttpServlet进一步针对 HTTP 协议将service()方法实现为请求类型分发器并提供了doGet()、doPost()等钩子方法。我们自定义的 Servlet 只需继承HttpServlet重写需要的doXxx()方法即可。三、Servlet 生命周期Servlet 由 Web 容器如 Tomcat管理其生命周期分为四个阶段加载实例化 → 初始化 → 服务 → 销毁。下面用流程图展示容器启动或首次请求加载Servlet类并实例化调用init方法初始化等待请求收到请求调用service方法容器关闭或应用卸载调用destroy方法释放资源各阶段详解阶段时机次数说明加载与实例化首次访问 Servlet 时或容器启动时若配置了load-on-startup1次通过反射调用无参构造器创建实例初始化实例化之后立即执行1次调用init(ServletConfig config)可用于加载资源、获取配置服务每次收到请求多次调用service()方法根据请求类型分发到doGet/doPost销毁容器正常关闭或应用被卸载时1次调用destroy()方法释放数据库连接等资源注意默认情况下Servlet 在第一次被访问时才加载实例化。若希望在容器启动时就完成加载可以在web.xml中配置load-on-startup正数数值越小优先级越高。init()只执行一次且是线程安全的容器保证单例。四、ServletConfig 与 ServletContext这两个接口是 Servlet 编程中获取配置和共享数据的关键。1. ServletConfig作用范围每个 Servlet 私有由容器在init()方法中传入。主要功能获取当前 Servlet 在web.xml中配置的初始化参数init-param。获取当前 Servlet 的名称servlet-name。获取全局的ServletContext对象。配置示例web.xmlservletservlet-nameDemoServlet/servlet-nameservlet-classcom.example.DemoServlet/servlet-classinit-paramparam-nameencoding/param-nameparam-valueUTF-8/param-value/init-param/servlet代码使用StringencodinggetServletConfig().getInitParameter(encoding);StringservletNamegetServletConfig().getServletName();ServletContextcontextgetServletConfig().getServletContext();2. ServletContext作用范围整个 Web 应用共享一个应用只有一个ServletContext对象。主要功能获取全局初始化参数在context-param中配置的参数所有 Servlet 均可读取。获取 Web 资源的绝对路径通过getRealPath(/)或getResourceAsStream()读取配置文件、图片等。作为域对象在多个 Servlet 之间共享数据setAttribute/getAttribute。配置示例web.xmlcontext-paramparam-nameglobalConfig/param-nameparam-valueproduction/param-value/context-param代码使用// 获取全局参数StringconfiggetServletContext().getInitParameter(globalConfig);// 获取文件真实路径StringrealPathgetServletContext().getRealPath(/WEB-INF/config.properties);// 存储共享数据getServletContext().setAttribute(userCount,100);Integercount(Integer)getServletContext().getAttribute(userCount);五、总结概念核心要点访问流程浏览器 → Web服务器 → 容器创建 req/res → 调用 service → 返回响应体系结构Servlet(接口) → GenericServlet(抽象类) → HttpServlet(抽象类) → 自定义Servlet生命周期实例化(1次) → init(1次) → service(多次) → destroy(1次)ServletConfig每个 Servlet 私有用于获取自身初始化参数及 ServletContextServletContext整个应用共享用于获取全局参数、资源路径、存储域数据