Servlet生命周期

回到首页☞

生命周期在java框架中是一个核心概念,如同上下文一样重要。
Servlet生命周期_第1张图片

每个Servlet都有自己的生命周期,Servlet的生命周期由Web服务器来维护。Servlet的生命周期遵循Servlet规范。

1、Servlet生命周期

GUI每次请求一个线程,效率低下。
Servlet启动按照配置加载(load-on-startup)和第一次请求加载,去处理所有用户请求。服务器关闭才销毁,相对复杂,不过由服务器来做。

Servlet会在服务器启动或第一次请求该Servlet的时候开始生命周期,在服务器结束的时候结束生命周期。无论请求多少次Servlet,最多只有一个Servlet实例。多个客户端并发请求Servlet的时候,服务器会启动多个线程分别执行Servlet的service()方法。

在Servlet对象的生命周期中,init(ServletConfig conf)方法与destroy()方法均只会被服务器执行一次,而service方法在每次客户端请求Servlet时都会被执行。
Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init()方法内,把销毁该资源的代码放入到destroy()方法内,而不需要每次处理请求都要初始化与销毁资源。

对于Servlet的init(ServletConfig conf)方法,HttpServlet提供了一个更简单的不带参数的替代方法init()。HttpServlet加载时会执行这个不带参数的init()方法,因此只需把代码放置到init()中就可以了。对于原来的ServletConfig参数,仍然可以通过getServletConfig()方法获取到。

2、个税计算器

这个是古老版本的案例,主要是为了说明一件事,通过init获取初始参数,不需要每次请求,都在doGet和goPost中获取。

2.1 web.xml配置

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.wht.demo.servlet.HelloServlet</servlet-class>
        <init-param>
            <param-name>startPoint</param-name>
            <param-value>5500</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

1 可以不配置,就会第一次才加载。

2.2 简单页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Test</title>
  <style>
    div, body, span {
      font-size: 16px;
    }
  </style>
</head>
<body>
<div align="center">
  <div>
    <form action="/FirstWeb/HelloServlet" method="post">
      <div align="center">
        <fieldset style="width: 80%">
          <legend>个税计算器</legend>
          <div align="left">
            <span>您的工资为: </span> <input type="text"
                                       name="income"/><span> 单位元</span>
          </div>
          <div align="left">
            <input type="submit" value="计算个税"/>
          </div>
        </fieldset>
      </div>
    </form>
  </div>
</div>
</body>
</html>

2.3 核心servlet

package com.wht.demo.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author JDIT
 */
public class HelloServlet extends HttpServlet {
  private static double startPoint = 0; //个税起征点,从配置文件中获取

  @Override
  public void init() throws ServletException {
    this.log("执行 int() 方法...");
    ServletConfig conf = this.getServletConfig();
    startPoint = Double.parseDouble(conf.getInitParameter("startPoint"));
  }

  protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {


  }

  protected void doPost(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws javax.servlet.ServletException, IOException {

    this.log("执行 doPost() 方法..................");
    resp.setCharacterEncoding("UTF-8");
    req.setCharacterEncoding("UTF-8");
    resp.setContentType("text/html");

    PrintWriter printWriter = resp.getWriter();
    printWriter.println("");
    printWriter.println("");

    printWriter.println("个人所得税");
    printWriter.println("");

    printWriter.println("

个人所得税
"); double income = new Double(req.getParameter("income")); double charge = income - startPoint; double tax = 0; if (charge < 0) { tax = 0; } else if (charge > 0 && charge <= 500) { tax = charge * 0.05; } else if (charge > 500 && charge <= 2000) { tax = charge * 0.1 - 25; } else if (charge > 2000 && charge <= 5000) { tax = charge * 0.15 - 125; } else if (charge > 5000 && charge <= 20000) { tax = charge * 0.2 - 375; } else if (charge > 20000 && charge <= 40000) { tax = charge * 0.25 - 1375; } else if (charge > 40000 && charge <= 60000) { tax = charge * 0.30 - 3375; } else if (charge > 60000 && charge <= 80000) { tax = charge * 0.35 - 6375; } else if (charge > 80000 && charge <= 100000) { tax = charge * 0.4 - 10375; } else if (charge > 100000) { tax = charge * 0.45 - 15375; } printWriter.println("
"); printWriter.println("您的工资为:" +income+ "元"); printWriter.println("
"
); printWriter.println("
"); printWriter.println("您应纳税:" +tax+ "元"); printWriter.println("
"
); printWriter.println("

"
); printWriter.println(""); printWriter.println(""); printWriter.flush(); printWriter.close(); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.log("执行 service() 方法.................."); super.service(req, resp); } }

09-Feb-2020 20:39:29.849 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 int() 方法…
09-Feb-2020 20:39:37.500 信息 [http-nio-10024-exec-6] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 service() 方法…
09-Feb-2020 20:39:37.500 信息 [http-nio-10024-exec-6] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 doPost() 方法…
09-Feb-2020 20:39:50.478 信息 [http-nio-10024-exec-4] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 service() 方法…
09-Feb-2020 20:39:50.478 信息 [http-nio-10024-exec-4] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 doPost() 方法…
09-Feb-2020 20:39:54.752 信息 [http-nio-10024-exec-8] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 service() 方法…
09-Feb-2020 20:39:54.752 信息 [http-nio-10024-exec-8] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 doPost() 方法…
09-Feb-2020 20:40:00.150 信息 [http-nio-10024-exec-9] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 service() 方法…
09-Feb-2020 20:40:00.150 信息 [http-nio-10024-exec-9] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 doPost() 方法…
09-Feb-2020 20:40:13.005 信息 [main] org.apache.catalina.core.ApplicationContext.log HelloServlet: 执行 destroy() 方法…

从运行结果看:

  • 如果配置了启动顺序,init方法会自动加载
  • 每次请求的时候,会先触发services方法再触发到doPost
  • 当应用服务停止,会触发destroy方法,销毁

2、注解@PostConstruct与注解@PreDestroy

这两个主机肉带回修饰一个非静态的void()方法,而且这个方法不能抛出异常声明。 注解可以放在方法上,也可以放在void前面。

  • @PostConstruct 带有这个注解的方法,会在构造方法后和init执行前自动执行。
  • @PreDestroy 销毁方法,会在销毁后执行
    服务器启动的时候,会遍历 WEB-INF/classes下面的所有class文件与WEB-INF/lib下的所有jar文件,检查哪些类使用了注解。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

如果项目中不支持注解可以在web.xml头部配置:metadata-complete=“true”

回到首页☞

你可能感兴趣的:(Java,Web)