Servlet相关介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_37988928/article/details/89815005

Servlet的三种创建方式:
    1、实现servlet接口,2、继承GenericServlet类,3、继承HttpServlet类

Servlet生命周期:
    Servlet通过调用init()方法进行初始化
    Servlet调用service()方法来处理客户端的请求
    Servlet通过调用destroy()方法终止(结束)
    最后,Servlet是由JVM的垃圾回收器进行垃圾回收的
    init()方法
        init方法被设计成只调用一次,它在第一次创建Servlet时被调用,在后续每次用户请求时不再调用,因此它是用于一次性初始化,就像Applet的init方法一样
        Servlet创建于用户第一次调用对应于该Servlet的URL时,但是您也可以指定Servlet在服务器第一次启动时被加载
        当用户调用一个Servlet时,就会创建一个Servlet实例,每一个用户请求都会产生一个新的线程,适当的时候移交给doGet或doPost方法,init()方法简单地创建或加载一些数据,这些数据将被用于Servlet的整个生命周期
        init方法的定义如下:
            public void init() throws ServletException {
                // 初始化代码............
            }
    service()方法
        service方法是执行实际任务的主要方法,Servlet容器(即Web服务器)调用service()方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端
        每次服务器接收到一个Servlet请求时,服务器会产生一个新的线程并调用服务,service()方法检查HTTP请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用doGet、doPost、doPut、doDelete等方法
        下面是该方法的特征:
            public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{
                if (method.equals("GET")) {
                    ..........
                } else if (method.equals("POST")) {
                    ..........
                }
                ..........
            }
        service方法由容器调用,service方法在适当的时候调用doGet、doPost、doPut、doDelete等方法,所以不用对service()方法做任何动作,只需要根据来自客户端的请求类型来重写doGet()或doPost()即可
    doGet()和doPost()方法是每次服务请求中最常用的方法,下面是这两种方法的特征
    doGet()方法
        GET请求来自于一个URL的正常请求,或者来自于一个未指定METHOD的HTML表单,它由doGet()方法处理
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // Servlet代码..........
        }
    doPost()方法
        POST请求来自于一个特别指定了METHOD为POST的HTML表单,它由doPost()方法处理。
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // Servlet代码..........
        }
    destroy()方法
        destroy方法只会被调用一次,在Servlet生命周期结束时被调用,destroy()方法可以让Servlet关闭数据库连接、停止后台线程、把Cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动
        在调用destroy()方法之后,servlet对象被标记为垃圾回收,destroy方法定义如下所示:
        public void destroy() {
            // 终止化代码.........
        }

Servlet线程安全问题:
    servlet是Singleton的,所以多个线程是可能会访问同一个servlet实例对象的
    Servlet本身是无状态的,一个无状态的Servlet是绝对线程安全的,无状态对象设计也是解决线程安全问题的一种有效手段
    线程安全问题都是由全局变量及静态变量引起的,由此可知servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之就是线程安全的

设计线程安全的Servlet:
    1、实现 SingleThreadModel接口 
        如果一个Servlet实现了SingleThreadModel接口,Servlet引擎将为每个新的请求创建一个单独的Servlet实例,这将引起大量的系统开销,在现在的Servlet开发中基本看不到SingleThreadModel的使用,这种方式了解即可,尽量避免使用
        public class XXXXX extends HttpServlet implements SingleThreadModel {
            ..........
        }
    2、同步对共享数据的操作
        使用synchronized关键字能保证一次只有一个线程可以访问被保护的区段,可以通过同步块操作来保证Servlet的线程安全。但在程序中使用同步来保护要使用的共享的数据,也会使系统的性能大大下降
        Public class XXXXXX extends HttpServlet {
            synchronized (this){XXXX}
        }
    3、避免使用实例变量
        线程安全问题很大部分是由实例变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的
        Java内存模型中,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全

猜你喜欢

转载自blog.csdn.net/weixin_37988928/article/details/89815005