您的位置:首页 > 其它

Timer + ServletContext 实现web应用的任务调度

2015-04-16 15:04 295 查看
ServletContext 被 Servlet 程序用来与 Web 容器通信。例如写日志,转发请求。每一个 Web 应用程序含有一个Context,被Web应用内的各个程序共享。因为Context可以用来保存资源并且共享,所以我所知道的 ServletContext 的最大应用是Web缓存----把不经常更改的内容读入内存,所以服务器响应请求的时候就不需要进行慢速的磁盘I/O了。

ServletContextListener 是 ServletContext 的监听者,如果 ServletContext 发生变化,如服务器启动时 ServletContext 被创建,服务器关闭时 ServletContext 将要被销毁。

在JSP文件中,application 是 ServletContext 的实例,由JSP容器默认创建。Servlet 中调用 getServletContext()方法得到 ServletContext 的实例。

我们使用缓存的思路大概是:

服务器启动时,ServletContextListener 的 contextInitialized()方法被调用,所以在里面创建好缓存。可以从文件中或者从数据库中读取取缓存内容生成类,用 ervletContext.setAttribute()方法将缓存类保存在 ServletContext 的实例中。

程序使用 ServletContext.getAttribute()读取缓存。如果是 JSP,使用a pplication.getAttribute()。如果是 Servlet,使用 getServletContext().getAttribute()。如果缓存发生变化(如访问计数),你可以同时更改缓存和文件/数据库。或者你等 变化积累到一定程序再保存,也可以在下一步保存。

服务器将要关闭时,ServletContextListener 的 contextDestroyed()方法被调用,所以在里面保存缓存的更改。将更改后的缓存保存回文件或者数据库,更新原来的内容。

import User; //my own class
import DatabaseManager; // my own class
import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;

public class MyContextListener

implements ServletContextListener {
private ServletContext context = null;

public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();
User user = DatabaseManager.getUserById(1);
context.setAttribute("user1", user);
}

public void contextDestroyed(ServletContextEvent event) {
User user = (User)context.getAttribute("user1");
DatabaseManager.updateUserData(user);
this.context = null;
}
}


布署 ServletContextListener

你实现(implements)了 ServletContextListener 编译后,把它放在正确的WEB-INF/classes目录下,更改WEB-INF目录下的 web.xml文件,在web-app节点里添加
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>

前面简述了ServletContext 的用法,以及配置,下面介绍与Timer 联合实现任务调度
编写一个ServletContext类,里面实现Timer实例

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import java.util.Timer;

import javax.servlet.ServletContextEvent;

import javax.servlet.ServletContextListener;

public class SapSchedule implements ServletContextListener {

// 上传时间间隔(按小时)

//private static final long UP_PERIOD = 24 * 60 * 60 * 1000;

private Timer timer = null;

//@Override

public void contextDestroyed(ServletContextEvent arg0) {

timer.cancel();

}

//@Override

public void contextInitialized(ServletContextEvent arg0) {

timer = new Timer(true);

Calendar calendar = Calendar.getInstance();

calendar.add(Calendar.SECOND, 15);

Date date = calendar.getTime();

System.out.println(date);

calendar.add(Calendar.MINUTE, 2);

date = calendar.getTime();

// 9999 休眠

if (SapServlet.interval!=9999) {

long PERIOD = 60 * 1000 * SapServlet.interval;

timer.schedule(new SapSynTask(), date, PERIOD);

}

}

}

编写Timer类对应的TimerTask

public class SapSynTask extends TimerTask {

@Override

public void run() {

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");

Date date = new Date();

System.out.println("任务开始时间:"+format.format(date));

try {

doSyn();

} catch (Exception e) {

System.out.println("###################{ SCHEDULE ERROR }####################");

e.printStackTrace();

}

date = new Date();

System.out.println("任务结束时间:"+format.format(date));

}

public void doSyn() {

// 做具体的任务事

}

}

public class SapServlet extends HttpServlet {

public static int hour = 0;

public static int minute = 0;

public static int second = 0;

// 时间间隔,默认10分钟

public static int interval = 10;

static {

InputStream stream = ConfigHelper.getResourceAsStream("/pos.cfg.xml");

SAXReader reader = new SAXReader();

Document doc = null;

try {

doc = reader.read(stream);

Element element = doc.getRootElement();

Element el2 = element.element("interval");

if (el2!=null) {

interval = Integer.parseInt(el2.getText());

}

} catch (DocumentException e1) {

e1.printStackTrace();

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: