以下使用一個簡單的範例,示範如何在Stateless Session Bean上使用Timer服務,客戶端可以指定時間啟動Timer,排定在某個時間送訊息給Message-Driven Bean。
首先定義一個簡單的介面:
- IMaintain.java
package onlyfun.caterpillar;
import java.util.Date;
import javax.ejb.Local;
@Local
public interface IMaintain {
public void scheduleMessage(Date expiration, String message);
}
在Stateless Session Bean實作部份,使用@Resource注入TimerService、ConnectionFactory與Destination:
- MaintainBean.java
package onlyfun.caterpillar;
import java.util.Date;
import javax.annotation.Resource;
import java.util.logging.*;
import javax.ejb.*;
import javax.jms.*;
@Stateless
public class MaintainBean implements IMaintain {
@Resource(name="jms/HelloQueueFactory")
private ConnectionFactory connectionFactory;
@Resource(name="jms/HelloQueue")
private Destination queue;
@Resource
private TimerService timerService;
public void scheduleMessage(Date expiration, String message) {
timerService.createTimer(expiration, message);
}
@Timeout
public void sendMessage(Timer timer) {
try {
String message = (String) timer.getInfo();
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(
false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue);
TextMessage textMessage = session.createTextMessage();
textMessage.setText(message);
producer.send(textMessage);
producer.close();
session.close();
connection.close();
} catch (JMSException ex) {
Logger.getLogger(
MaintainBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
如果您想要從EJBContext中取得TimerService,則可以如下:
...
@Resource
private SessionContext context;
public void scheduleMessage(Date expiration, String message) {
TimerService timerService = context.getTimerService();
timerService.createTimer(expiration, message);
}
....
@Resource
private SessionContext context;
public void scheduleMessage(Date expiration, String message) {
TimerService timerService = context.getTimerService();
timerService.createTimer(expiration, message);
}
....
若不使用@Timeout標註,則您要實作TimedObject介面,實作其void ejbTimeout(Timer timer)方法。
為了配合這個範例,改寫一下 第 一個 Message-Driven Bean 中的Message-Driven Bean範例:
- HelloMessageBean.java
package onlyfun.caterpillar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(mappedName = "jms/HelloQueue",
activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode",
propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
})
public class HelloMessageBean implements MessageListener {
public void onMessage(Message message) {
try {
TextMessage txtMessage = (TextMessage) message;
System.out.println(txtMessage.getText() + " processed....Orz");
} catch (JMSException ex) {
Logger.getLogger(HelloMessageBean.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
以下是個簡單的Servlet客戶端測試,排定在呼叫後的10秒鐘執行:
- HelloServlet.java
package onlyfun.caterpillar;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import javax.ejb.EJB;
public class HelloServlet extends HttpServlet {
@EJB
private IMaintain maintain;
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MILLISECOND, 10000);
maintain.scheduleMessage(calendar.getTime(), "save me....XD");
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
public String getServletInfo() {
return "Short description";
}
}