Tomcat服务器开机启动时执行某段程序

来源:互联网 发布:数据库引擎是什么 编辑:程序博客网 时间:2024/06/05 05:49

前段时间在做一个远程控制系统的网站开发,系统要求能够设定定时开关机功能。在网页中设定时间后,服务器将数据存储进数据库,隔一段时间从数据库中读取设定时间值与当前时间进行比较来决定是否执行程序功能。

在查阅网络资料后找到一个方法来实现这个功能:实现ServletContextListener这个接口,当创建ServletContext时,激发contextInitialized方法,在contextInitialized方法中实现你的功能。
由于我的定时开关机功能开启成功与否标志放在服务器的全局变量,即application对象中。而此时spring还没有加载,无法注入。此时就用服务器提供的监听器来实现。

MyTimer类:

package com.hust.timer;import java.util.Calendar;import java.util.Timer;import java.util.TimerTask;import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.springframework.context.ApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import com.hust.bean.Constant;import com.hust.bean.PumpHost;import com.hust.bean.PviState;import com.hust.bean.SetInfo;import com.hust.serial.CRC16;import com.hust.serial.SerialBean;import com.hust.service.PumpHostService;import com.hust.service.PviStateService;import com.hust.service.SetInfoService;public class MyTimer implements ServletContextListener {private Timer timer = null;private String aa;private PumpHostService phService;private PviStateService psService;private SetInfoService siService;private PumpHost ph;private PviState ps;private SetInfo si;//ServletContextEvent atest;@Override public void contextDestroyed(ServletContextEvent arg0) { timer.cancel(); } @Override public void contextInitialized(ServletContextEvent sce) {  ApplicationContext ac = WebApplicationContextUtils         .getWebApplicationContext(sce.getServletContext());  //设置在application中//sce.getServletContext().setAttribute("flag", 5); //通过spring注入,配置listener监听器在spring的后面,等spring先初试化完成//SetInfoDao siDao = (SetInfoDao)ac.getBean("siDao");siService = (SetInfoService)ac.getBean("siService");phService = (PumpHostService)ac.getBean("phService");psService = (PviStateService)ac.getBean("psService");timer = new Timer();  //设置任务计划,启动和间隔时间 timer.schedule(new MyTask(), 200, 10); //timer.schedule(new aaTask(), 200, 1000); timer.schedule(new turnOn(sce.getServletContext()), 200, 60*1000);timer.schedule(new turnOff(sce.getServletContext()), 200, 60*1000);}private class turnOn extends TimerTask{//采用构造函数传递application对象,从而进行参数设置private ServletContext servletContext;public turnOn(ServletContext servletContext){this.servletContext = servletContext;}public void run(){aa = siService.getFirsSetInfo().getSetTimeOn();System.out.println("从数据库中读出来的开启时间: "+aa);String bb,cc;if(aa.length()==4){ bb = aa.substring(0, 1); cc = aa.substring(2, 4);}else { bb = aa.substring(0, 2); cc = aa.substring(3, 5);}int h = Integer.parseInt(bb);int m = Integer.parseInt(cc);System.out.println("处理后格式:"+h+"时"+m+"分");//System.out.println("时钟: "+ b);//System.out.println("分钟: "+ c);Calendar xx = Calendar.getInstance();int hour = xx.get(Calendar.HOUR_OF_DAY);int min = xx.get(Calendar.MINUTE);int sec = xx.get(Calendar.SECOND); System.out.println("系统时间:"+hour+"时"+min+"分"+sec+"秒");if(h==hour && m==min){//要执行的程序代码System.out.println("执行一次");//每次取最新一条记录,所以应在函数里面//si = siService.getFirsSetInfo();//ph = phService.getFirstPumpHost();//ps = psService.getFirstPviSate();//判断数据库中读出日期时间//发送控制协议命令//判断总线是否空闲if(MyTask.safeCount>=10) {/*这里完成向串口发送控制信号数据包*/  //组装字节数组byte[] bts = new  byte[6];byte[] bts2 = new byte[8];bts[0] = 0x01; //第1个字节表示从机地址,这里设为1bts[1] = 0x10; //第2个字节表示功能码,//总开关bts[2] = (byte) 0xee; //第3个字节表示数据类型bts[3] = 0x02; //第4个字节表示数据长度2//打开总开关bts[4] = 0x00;   //填充bts[5] = 0x01;  //自动int c = CRC16.crcTable(bts);SerialBean serialBean = new SerialBean(1);if (serialBean.Initialize()==1) { //发送数据for (int i = 0; i < 6; i++) {bts2[i] = bts[i];}bts2[6] = (byte) (c%256); //第5个字节表示crc检验低位bts2[7] = (byte) (c/256); //第6个字节表示crc检验高位serialBean.WritePortBytes(bts2);  //计数器清零MyTask.safeCount = 0;}else {System.out.println("串口打开失败,请尝试重新发送!") ;//return "error";//设置标志位flag,用来指示自动开启是否成功,放在application对象中,全局有效。//servletContext.setAttribute("flag",(Integer)(-1));servletContext.setAttribute("flagOn","   定时开启失败");}System.out.println("成功发送!") ;//servletContext.setAttribute("flag", (Integer)1);servletContext.setAttribute("flagOn", "   定时开启成功");System.out.println("****************************") ;//return "success";}else {System.out.println("串口总线被占用,请尝试重新发送!!") ;//servletContext.setAttribute("flag", (Integer)0);servletContext.setAttribute("flagOn", "   总线占用,开启失败");//return "error";}}}}private class turnOff extends TimerTask{//采用构造函数传递application对象,从而进行参数设置private ServletContext servletContext;public turnOff(ServletContext servletContext){this.servletContext = servletContext;}public void run(){aa = siService.getFirsSetInfo().getSetTimeOff();System.out.println("从数据库中读出来关闭的时间: "+aa);String bb,cc;if(aa.length()==4){bb = aa.substring(0, 1);cc = aa.substring(2, 4);}else {bb = aa.substring(0, 2);cc = aa.substring(3, 5);}int h = Integer.parseInt(bb);int m = Integer.parseInt(cc);System.out.println("处理后格式:"+h+"时"+m+"分");//System.out.println("时钟: "+ b);//System.out.println("分钟: "+ c);Calendar xx = Calendar.getInstance();int hour = xx.get(Calendar.HOUR_OF_DAY);int min = xx.get(Calendar.MINUTE);int sec = xx.get(Calendar.SECOND); System.out.println("系统时间:"+hour+"时"+min+"分"+sec+"秒");if(h==hour && m==min){//要执行的程序代码System.out.println("执行一次");//每次取最新一条记录,所以应在函数里面//si = siService.getFirsSetInfo();//ph = phService.getFirstPumpHost();//ps = psService.getFirstPviSate();//判断数据库中读出日期时间//发送控制协议命令//判断总线是否空闲if(MyTask.safeCount>=10) {/*这里完成向串口发送控制信号数据包*/  //组装字节数组byte[] bts = new  byte[6];byte[] bts2 = new byte[8];bts[0] = 0x01; //第1个字节表示从机地址,这里设为1bts[1] = 0x10; //第2个字节表示功能码,//总开关bts[2] = (byte) 0xee; //第3个字节表示数据类型bts[3] = 0x02; //第4个字节表示数据长度2//关闭总开关bts[4] = 0x00;   //填充bts[5] = 0x00;  //自动int c = CRC16.crcTable(bts);SerialBean serialBean = new SerialBean(1);if (serialBean.Initialize()==1) { //发送数据for (int i = 0; i < 6; i++) {bts2[i] = bts[i];}bts2[6] = (byte) (c%256); //第5个字节表示crc检验低位bts2[7] = (byte) (c/256); //第6个字节表示crc检验高位serialBean.WritePortBytes(bts2);  //计数器清零MyTask.safeCount = 0;}else {System.out.println("串口打开失败,请尝试重新发送!") ;//return "error";//设置标志位flag,用来指示自动开启是否成功,放在application对象中,全局有效。//servletContext.setAttribute("flag",(Integer)(-1));servletContext.setAttribute("flagOff","   定时关闭失败");}System.out.println("成功发送!") ;//servletContext.setAttribute("flag", (Integer)1);servletContext.setAttribute("flagOff", "   定时开启成功");System.out.println("****************************") ;//return "success";}else {System.out.println("串口总线被占用,请尝试重新发送!!") ;//servletContext.setAttribute("flag", (Integer)0);servletContext.setAttribute("flagOff", "   总线占用,开启失败");//return "error";}}}}}

MyTask类中是具体定时要实现的功能,turnOn和turnOff是定时开关程序功能。

web.xml文件中进行监听器配置:

  <!-- 开机自启动的任务监听器配置 -->  <listener>             <listener-class>com.hust.timer.MyTimer</listener-class>     </listener> 




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信账号卖了但是实名认证了怎么办 uc下载文档里的文档全没了怎么办 二手乐视没有账号和密码怎么办 华为账号密码忘了手机卡丢了怎么办 联想平板微信更新后不可兼容怎么办 小米手机刷完机账号密码忘了怎么办 红米手机的小米账号密码忘了怎么办 小米手机账号密码手机号忘了怎么办 小米手机忘了账号和密码怎么办 自己的小米账号密码忘了怎么办 小米手机丢了不记得小米账号怎么办 小米手环账号密码忘了怎么办 阴阳师一个区的账号找不到了怎么办 阴阳师手机账号代练登录了后怎么办 我的微信账号被盗更改密码了怎么办 vivo手机密保密码忘了怎么办 华为手机保密柜忘记密保问题怎么办 支付宝账号突然说没有了怎么办 快手号密码可能被盗登不上该怎么办 海岛奇兵小米版换手机了怎么办 申诉找回微信密码验证吗错误怎么办 微信密码忘了申诉不成功怎么办 微信密码忘了申诉不了怎么办 微信密码忘了申诉不回来怎么办 微信号密码忘了申诉失败怎么办 手机微信密码忘了无需申诉怎么办 安全守护2手机绑定密码错误怎么办 新办的手机号注册过魅族账号怎么办 百度网盘手机找回被别人关了怎么办 把朋友微信号弄没了怎么办 小米顶配版手机无线网速度慢怎么办 刺激战场用过模拟器后用手机怎么办 百度网盘分享文件有违禁内容怎么办 百度网盘好友发的分享不存在怎么办 4g手机的下载速度很慢怎么办 为什么打开百度网盘的速度慢怎么办 百度网盘限制了我的宽带速度怎么办 联通信号很好但网速特别慢怎么办 苹果手机版本低下载不了软件怎么办 国内的手机要上推特和油管要怎么办 推特注册了卡在手机号怎么办