JavaWeb之Servlet

一、Servlet对象生命周期

1. Servlet对象什么时候被创建

在进行请求的时候通过反射机制,调用无参构造方法,创建Servlet对象。
思考:服务器在启动时Servlet对象有没有被创建出来?
在Servlet中提供一个无参数的构造方法,启动服务器的时候看看构造方法是否执行。

public TestServlet() {
        System.out.println("servlet无参构造方法执行了");
    }
    // 经过测试得出结论:默认情况下,服务器在启动的时候Servlet对象并不会被实例化。
	//这个设计是合理的。用户没有发送请求之前,如果提前创建出来所有的Servlet对象,必然是耗费内存的,并且创建出来的Servlet如果一直没有用户访问,显然这个Servlet对象是一个废物,没必要先创建。

那么如何才能让服务器启动的时候创建Servlet对象?
在servlet标签中添加子标签,在该子标签中填写整数,越小的整数优先级越高。

    <servlet>
        <servlet-name>aservlet</servlet-name>
        <servlet-class>com.bjpowernode.servlet.TestServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>aservlet</servlet-name>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

用户发送第一次请求的时候,控制台输出了以下内容:(在方法中添加了对应的输出语句测试)
在这里插入图片描述
根据以上输出内容得出结论:

  • 用户在发送第一次请求的时候Servlet对象被实例化(TestServlet的构造方法被执行了。并且执行的是无参数构造方法。)
  • TestServlet对象被创建出来之后,Tomcat服务器马上调用了TestServlet对象的init方法。(init方法在执行的时候,TestServlet对象已经存在了。已经被创建出来了。)
  • 用户发送第一次请求的时候,init方法执行之后,Tomcat服务器马上调用TestServlet对象的service方法。

用户继续发送第N次请求,控制台输出了以下内容:
在这里插入图片描述
根据以上输出结果得知,用户在发送第二次,或者第三次,或者第四次请求的时候,Servlet对象并没有新建,还是使用之前创建好的Servlet对象,直接调用该Servlet对象的service方法,这说明:

  • 第一:Servlet对象是单例的(单实例的。但是要注意:Servlet对象是单实例的,但是Servlet类并不符合单例模式。我们称之为假单例。这个对象的创建只能是Tomcat来说了算,Tomcat只创建了一个,所以导致了单例,但是属于假单例。真单例模式,构造方法是私有化的。)
  • 第二:无参数构造方法、init方法只在第一次用户发送请求的时候执行。也就是说无参数构造方法只执行一次。init方法也只被Tomcat服务器调用一次。
  • 第三:只要用户发送一次请求:service方法必然会被Tomcat服务器调用一次。发送100次请求,service方法会被调用100次。

关闭服务器的时候,控制台输出了以下内容:
在这里插入图片描述
通过以上输出内容,可以得出以下结论:

  • Servlet的destroy方法只被Tomcat服务器调用一次。
  • destroy方法是在什么时候被调用的?
    • 在服务器关闭的时候。
    • 因为服务器关闭的时候要销毁TestServlet对象的内存。
    • 服务器在销毁TestServlet对象内存之前,Tomcat服务器会自动调用TestServlet对象的destroy方法。

二、GenericServlet

  • 编写一个Servlet类直接实现Servlet接口有什么缺点?

    答:我们只需要service方法,其他方法大部分情况下是不需要使用的。代码很丑陋。因此提出了适配器设计模式Adapter

  • 编写一个GenericServlet类,这个类是一个抽象类,其中有一个抽象方法service。
    - GenericServlet实现Servlet接口。
    - GenericServlet是一个适配器。
    - 以后编写的所有Servlet类继承GenericServlet,重写service方法即可。

public abstract class GenericServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    
    @Override
    public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
    
    @Override
    public String getServletInfo() {
        return null;
    }
    
    @Override
    public void destroy() {
    }
}
public class LoginServlet extends GenericServlet{
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("login中的service方法执行了");
    }
}

总结

  • Servlet对象更像一个人的一生:
    • Servlet的无参数构造方法执行:标志着出生了。
    • Servlet对象的init方法的执行:标志着正在接受教育。
    • Servlet对象的service方法的执行:标志着已经开始工作了,已经开始为人类提供服务了。
    • Servlet对象的destroy方法的执行:标志着临终。有什么遗言,抓紧的。要不然,来不及了。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值