References:《 Tomcat 啟動時加載WEB應用中的后臺程序 》[1],《 配置Tomcat Listener 》[2]
?
要做的事情很簡單,就是在Tomcat啟動WEB服務器的時候同時啟動一個后臺程序,做一些事情。
[1]里面介紹的方法是通過不響應Request的Servlet來實現,通過設置<load-on-startup>標簽和Servlet里面的static代碼段來實現。
[2]介紹了另一個方法,通過實現ServletContextListener,并在web.xml文件里配置listener來實現后臺程序的啟動。
于是我打算先用第二種方法做一個demo:實現的功能:用戶在頁面輸入值,action把這個值甩到一個消息隊列里面,然后后臺這個線程不斷的從這個隊列里面讀值,輸出到控制臺
MyListener.java??? version1
package
Listeners;
import
javax.servlet.ServletContextEvent;
import
javax.servlet.ServletContextListener;
import
Support.MessageQManager;
import
Support.MessageQueue;
public
class
MyListener
implements
ServletContextListener {
@Override
public
void
contextInitialized(ServletContextEvent sce) {
System.err.println("
DBConnListener Startup!
");
DemoThread dt =
new
DemoThread(MessageQManager.mq);
Thread th1 =
new
Thread(dt);
th1.start();
System.err.println("
DemoThread Startup!
");
}
@Override
public
void
contextDestroyed(ServletContextEvent sce) {
}
}
DemoThread.java? ---version1
package
BackStage;
import
Support.MessageQueue;
public
class
DemoThread
implements
Runnable {
private
MessageQueue mq=
null
;
public
DemoThread(MessageQueue mq){
this
.mq=mq;
}
public
void
run() {
while
(
true
){
readFromMsgQueue();
}
}
public
Object readFromMsgQueue(){
Object o=mq.recv();
System.err.println(o.toString());
return
o;
}
}
MessageQueue.java
package
Support;
import
java.util.Vector;
public
class
MessageQueue {
private
Vector<Object> queue =
null
;
public
MessageQueue() {
queue =
new
Vector<Object>();
}
public
synchronized
void
send(Object o) {
queue.addElement(o);
}
public
synchronized
Object recv() {
if
(queue.size() == 0)
return
null
;
Object o = queue.firstElement();
queue.removeElementAt(0);
// or queue[0] = null can also work
return
o;
}
}
MessageQManager.java
package
Support;
public
class
MessageQManager {
public
static
MessageQueue mq=
new
MessageQueue();
}
前端代碼就不貼出來了,就是把輸入的值send到消息隊列里面。
web.xml配置片段: <listener>標簽要在filter-mapping標簽下面
<
listener
>
<
listener
-
class
>
Listeners.MyListener
</
listener
-class
>
</
listener
>
然后滿心歡喜的用eclipse啟動服務器呢!O(∩_∩)O~
結果呢~出錯了!!(⊙_⊙)
NoClassDefFoundError! 搜了一把,很多是因為找不到ServletContextListener,但是我的是能找到的,只是找不到自定義的類而已。研究了一段時間發現跟tomcat加載class的時間跟順序有關系,貌似挺復雜的……沒研究明白。
不管了先跑起來再說,于是果斷把DemoThread甩到MyListener里面當一個內部類
MyListener.java??? version2
package
Listeners;
import
javax.servlet.ServletContextEvent;
import
javax.servlet.ServletContextListener;
import
Support.MessageQManager;
import
Support.MessageQueue;
public
class
MyListener
implements
ServletContextListener {
@Override
public
void
contextInitialized(ServletContextEvent sce) {
System.err.println("
DBConnListener Startup!
");
DemoThread dt =
new
DemoThread(MessageQManager.mq);
Thread th1 =
new
Thread(dt);
th1.start();
System.err.println("
DemoThread Startup!
");
}
@Override
public
void
contextDestroyed(ServletContextEvent sce) {
}
public
class
DemoThread
implements
Runnable {
private
MessageQueue mq =
null
;
public
DemoThread(MessageQueue mq) {
this
.mq = mq;
}
public
void
run() {
while
(
true
) {
readFromMsgQueue();
}
}
public
Object readFromMsgQueue() {
Object o = mq.recv();
if
(o !=
null
)
System.err.println(o.toString());
return
o;
}
}
}
在運行,成功。
?
Demo是成功了,可是問題還有:
只能用內部類的方式不是太傻了么……怎樣在Tomcat啟動的時候加載自定義的類呢?理想狀態是通過這一個線程作為入口啟動好多個后臺程序呢。
------------------- 3月30日 更?? 新 --------------------------
今天早上又用第一種方法嘗試了一下,沒有使用static代碼段,而是在init()方法里啟動線程,但是依然出現ClassNotFound的錯誤,直覺告訴我可能是 DemoThread寫的有問題 ,于是增加了 空的構造函數 !居然成功了!!
新的DemoThread.java代碼
package
BackStage;
import
Support.MessageQManager;
import
Support.MessageQueue;
public
class
DemoThread
implements
Runnable {
public
DemoThread() {
System.err.println("
DemoThread default constructor
");
}
public
void
run() {
while
(
true
) {
readFromMsgQueue(MessageQManager.mq);
}
}
public
Object readFromMsgQueue(MessageQueue mq) {
Object o = mq.recv();
if
(o !=
null
)
System.err.println(o.toString());
return
o;
}
}
代碼用System.err主要是紅色的輸出信息比較惹眼哈╮(╯▽╰)╭
MyListener –version3
package
Listeners;
import
javax.servlet.ServletContextEvent;
import
javax.servlet.ServletContextListener;
import
BackStage.DemoThread;
public
class
MyListener
implements
ServletContextListener {
@Override
public
void
contextInitialized(ServletContextEvent sce) {
System.err.println("
DBConnListener Startup!
");
DemoThread dt =
new
DemoThread();
Thread th1 =
new
Thread(dt);
th1.start();
System.err.println("
DemoThread Startup!
");
}
@Override
public
void
contextDestroyed(ServletContextEvent sce) {
}
}
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

