WebLogic Server包含了Timer Service功能,你可以指定某一时刻或某一时间间隔产生Timer事件,同时你可以使用委托代理的机制,为这个事件注册事件监听器,以实现Timer Service功能。
从WebLogic Server 7.0以后的版本,WebLogic Timer Service扩展自标准的JMX Timer Service,使其可以运行于WebLogic Server的执行线程中,并且享有WebLogic Server的安全上下文环境,也就是说,可以在代码中得到安全信息,如用户名等。下面结合一个实例演示其功能。
File:TimerServiceListener.java
package org.yekki.weblogic.timer;
import java.util.Date;
import java.util.Random;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.management.InstanceNotFoundException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.ecs.xml.XML;
import weblogic.management.timer.Timer;
public class TimerServiceListener
implements ServletContextListener, NotificationListener {
private long period;
private boolean debug;
private Timer timer;
private Integer notificationId;
private QueueConnectionFactory factory;
private QueueConnection connection;
private QueueSession session;
private QueueSender sender;
private Queue queue;
private Context ctx;
public void contextInitialized(ServletContextEvent event) {
initParams(event);
initJMS();
debug(">>> contextInitialized called.");
timer = new Timer();
timer.addNotificationListener(this, null, "Message Broker ");
Date timerTriggerAt = new Date((new Date()).getTime() + 5000L);
notificationId =
timer.addNotification(
"Timer Type",
"Timer Message",
this,
timerTriggerAt,
period);
timer.start();
debug(">>> timer started.");
printBrief();
}
public void initParams(ServletContextEvent event) {
ServletContext ctx = event.getServletContext();
try {
debug = Boolean.valueOf((String)ctx.getInitParameter("debug")).booleanValue();
}
catch (Exception e) {
debug = false;
e.printStackTrace();
}
try {
/*
second:1000L
minute:60000L
hour:3600000L
day:86400000L
week:604800000L
*/
period =
Long
.valueOf((String)ctx.getInitParameter("period"))
.longValue();
}
catch (Exception e) {
period = Timer.ONE_MINUTE;
e.printStackTrace();
}
debug(">>> initialized application parameters.");
}
private void initJMS() {
try {
ctx = new InitialContext();
factory =
(QueueConnectionFactory)ctx.lookup(
"javax.jms.QueueConnectionFactory");
queue = (Queue)ctx.lookup("queue");
connection = factory.createQueueConnection();
session =
connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
sender = session.createSender(queue);
connection.start();
debug(">>> initialized jms.");
}
catch (Exception e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
try {
TextMessage msg = session.createTextMessage();
msg.setText(message);
sender.send(msg);
debug(">>> ################################");
debug("Send a message on " + new Date());
debug(message);
debug(">>> ################################");
}
catch (JMSException e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent event) {
debug(">>> contextDestroyed called.");
try {
timer.stop();
timer.removeNotification(notificationId);
debug(">>> timer stopped.");
}
catch (InstanceNotFoundException e) {
e.printStackTrace();
}
try {
if (session != null)
session.close();
if (connection != null)
connection.close();
debug(">>> closed jms connection and session.");
}
catch (JMSException e) {
e.printStackTrace();
}
}
private void printBrief() {
String d = "";
d = debug ? "ON" : "OFF";
print(">>> ################################");
print(">>> Author: Niu Xiuyuan");
print(">>> EMail: niuxiuyuan@bea.com.cn");
print(">>> Company: BEA Systems");
print("");
print(">>> Debug: " + d);
print(">>> Period: " + getPeriodInfo(period));
print(">>> ################################");
}
private void print(String str) {
System.out.println(str);
}
private String getPeriodInfo(long p) {
if (p == Timer.ONE_DAY)
return "One Day";
if (p == Timer.ONE_HOUR)
return "One Hour";
if (p == Timer.ONE_MINUTE)
return "One Minute";
if (p == Timer.ONE_SECOND)
return "One Second";
if (p == Timer.ONE_WEEK)
return "One Week";
return "Unsupported time period!! period=" + p;
}
public void handleNotification(Notification notif, Object handback) {
Random rnd = new Random();
sendMessage(genXML(rnd.nextInt(10)));
}
public String genXML(int id) {
String username = "guru";
String password = "niu986";
XML usernameXML = null;
XML idXML = null;
XML passwordXML = null;
XML userXML = null;
XML profileXML = new XML("profiles");
for (int i = 1; i <= id; i++) {
usernameXML = (new XML("user")).addElement(username);
idXML = (new XML("id")).addElement(Integer.toString(id));
passwordXML = (new XML("password")).addElement(password);
userXML =
(new XML("user"))
.addXMLAttribute("age", "27")
.addElement(idXML)
.addElement(usernameXML)
.addElement(passwordXML);
profileXML.addElement(userXML);
}
return profileXML.toString();
}
private void debug(String msg) {
if (debug) {
System.out.println(msg);
}
}
public static void main(String[] args) {
}
}
说明:为了方便演示,此类中包含了事件产生器代码与事件监听器代码。使用ServletContextListener接口来控制Timer的启动与停止。
File:web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>period</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>org.yekki.weblogic.timer.TimerServiceListener</listener-class>
</listener>
<login-config>
<auth-method></auth-method>
</login-config>
</web-app>
说明:我们将webapp的Lisener注册,并且指定事件产生的时间间隔
将此WebApp部署到WebLogic Server上,然后通过中端(例如:DOS窗口)查看实验结果。
附:本例中使用了Apache的ECS项目类库,您可以访问如下URL:
http://jakarta.apache.org/ecs/index.html