前幾天,manager問道一個問題:能不能實現類似於cron的后台管理方式。問題解決后,想對這幾個問題進行一下簡單的總結。以便拋磚引玉!首先簡單的提及一下cron。
Cron,計划任務,是任務在約定的時間執行已經計划好的工作,這是表面的意思。在Linux中,我們經常用到 cron 服務器來完成這項工作。cron服務器可以根據配置文件約定的時間來執行特定的作務。比如我們可以在配置文件中約定每天早上4點,對http服務器重新啟動,這就是一個計划任務。
在java應用中一種類似的模式就是應用啟動時后台線程的運行,定時的觸發某些任務的運行。目前,這種自啟動的后台線程,有兩種常見的模式:一種是listener,一種是servlet
(2)listener
listener方式是比較常用的。實際上,servelet API 提供了大量監聽器來監聽web應用的內部事件,從而允許當web應用內部事件發生時而回調監聽器的方法,常見的事件有:web應用被啟動、web應用被停止、用session開始、用戶session結束、用戶請求到達等。
其中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進行一下配置:
(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進行一下配置:

啟動項目,你同樣會發現你媽媽喊你回家吃飯。。。。
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之前。
下面來看一后台啟動的打印截圖,你就會發現!
第一種方式:


