设为首页 收藏本站
查看: 1007|回复: 0

[经验分享] Tomcat 启动后台程序

[复制链接]

尚未签到

发表于 2015-8-7 00:13:22 | 显示全部楼层 |阅读模式
  References:《Tomcat 启动时加载WEB应用中的后台程序》[1],《配置Tomcat Listener》[2]
  
  要做的事情很简单,就是在Tomcat启动WEB服务器的时候同时启动一个后台程序,做一些事情。
  [1]里面介绍的方法是通过不响应Request的Servlet来实现,通过设置标签和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 queue = null;
public MessageQueue() {
queue = new Vector();
}
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配置片段:标签要在filter-mapping标签下面


Listeners.MyListener
  然后满心欢喜的用eclipse启动服务器呢!O(∩_∩)O~
  结果呢~出错了!!(⊙_⊙)
DSC0000.png
  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) {

}
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-94867-1-1.html 上篇帖子: tomcat-users.xml 配置 下篇帖子: android与tomcat服务器交互实例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表