• Web应用启动时,后台自动启动一个线程


    (1)前言

        前几天,manager问道一个问题:能不能实现类似于cron的后台管理方式。问题解决后,想对这几个问题进行一下简单的总结。以便抛砖引玉!首先简单的提及一下cron。

        Cron,计划任务,是任务在约定的时间执行已经计划好的工作,这是表面的意思。在Linux中,我们经常用到 cron 服务器来完成这项工作。cron服务器可以根据配置文件约定的时间来执行特定的作务。比如我们可以在配置文件中约定每天早上4点,对http服务器重新启动,这就是一个计划任务。

        在java应用中一种类似的模式就是应用启动时后台线程的运行,定时的触发某些任务的运行。目前,这种自启动的后台线程,有两种常见的模式:一种是listener,一种是servlet

    (2)listener

        listener方式是比较常用的。实际上,servelet API 提供了大量监听器来监听web应用的内部事件,从而允许当web应用内部事件发生时而回调监听器的方法,常见的事件有:web应用被启动、web应用被停止、用session开始、用户session结束、用户请求到达等。

    Web应用启动时,后台自动启动一个线程

        其中ServletContextListener用于web应用的启动和关闭。对于我们刚刚提及的需求,我们需要在web应用启动的时候就开始启动后台的服务线程。

        ServletContextListener有两个常用的方法:

        void contextInitialized(ServletContextEvent sce)

        这个方法在Container初始化整个Web应用时调用,运行在该Web应用中servlet和filter初始化之前

        void contextDestroyed(ServletContextEvent sce)

        这个方法在Container卸载整个Web应用时调用,运行在该Web应用中servlet和filter的destroy()方法之后

    例子:

        首先定义一个后台的服务线程

    public class run implements Runnable{

     @Override
     public void run() {
      while(true){
       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
        e.printStackTrace();
       }
        System.out.println("you mother call you to go home to eat......")
      }

     }

    }

        定义一个listener类

    package com.cims; 
     
    import javax.servlet.ServletContextEvent; 
    import javax.servlet.ServletContextListener; 
     
     
    public class MyListener implements ServletContextListener {  
        public void contextDestroyed(ServletContextEvent e) {   
        } 
     
        public void contextInitialized(ServletContextEvent e) {  
                System.out.println("------------web start-------");

                new Thread(new run()).start();

        } 

    最后需要在web.xml进行一下配置:

    Web应用启动时,后台自动启动一个线程
    启动项目,你就会发现你妈妈喊你回家吃饭。。。。

    (3)servlet

        无意中,尽然惊讶地发现servlet也有这样的功能,这得益于load-on-startup 属性,后面将对该属性进行一些简单解析。

    服务线程仍然保持不变,写一个servlet(集成HttpServlet)

    package com.cims;  
    import java.io.IOException; 
    import javax.servlet.*; 
    import javax.servlet.http.*;  
     
    public class MyServlet extends HttpServlet{ 
     
        private static final long serialVersionUID = 1L;  
        public MyServlet(){ 
        }  
        public void init(){  

           new Thread(new run()).start();
        }  
        public void doGet(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) 
            throws ServletException, IOException{ 
        } 
     
        public void destory(){  
        } 
        } 

    最后需要在web.xml进行一下配置:

    Web应用启动时,后台自动启动一个线程
    启动项目,你同样会发现你妈妈喊你回家吃饭。。。。
    1.load-on-startup解析

        1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。

        2)它的值必须是一个整数,表示servlet应该被载入的顺序

        3)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;

        4)当值小于0或者没有指定时,可以由server容器自行决定何时load该servlet。

        5)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

        6)当值相同时,容器就会自己选择顺序来加载。   

    2.两种回家吃饭方式不同

        web应用的启动好比你正在start的一个游戏,listener好比在你start之前你妈妈就喊你回家吃饭了;servlet方式好比你已经start了,准备打boss时,你妈妈喊你回家吃饭。原因在于ServletContextListener的contextInitialized方法运行在servlet之前。

       下面来看一后台启动的打印截图,你就会发现!

        第一种方式:

     

  • 相关阅读:
    PHP 数组函数分类整理
    mysql 数据库中 int(3) 和 int(11) 有区别么???
    理解PHP的运行机制
    类与对象
    PHP函数补完:call_user_func()
    linux 软件安装目录详解
    Linux下安装Redis
    Redis简介,应用场景,优势
    idea自动抽取变量快捷键设置
    全局捕获异常(适用于SpringMvc,SpringBoot项目)
  • 原文地址:https://www.cnblogs.com/Nicolasap/p/8214420.html
Copyright © 2020-2023  润新知