Java 如何在部署时启动 EJB 计时器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1265914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to start an EJB Timer on deployment?
提问by scheibk
I need to create an interval Timer that is set to run once a week automatically. I don't want it to start based on user input, but I want it to be created when the application is deployed to the server. Every example that I have seen has another class starting the timer. I don't want to use a message driven bean to create the timer because the audit should just query a database for a given time period and is not based off of actions which send messages.
我需要创建一个设置为每周自动运行一次的间隔计时器。我不希望它根据用户输入启动,但我希望在将应用程序部署到服务器时创建它。我见过的每个例子都有另一个类启动计时器。我不想使用消息驱动的 bean 来创建计时器,因为审计应该只查询给定时间段的数据库,而不是基于发送消息的操作。
I have included an example of a Timer. In the example below, the timer should fire every 10 minutes. As a test I want the timer to fire every 10 minutes so I can test the timer.
我已经包含了一个计时器的例子。在下面的示例中,计时器应每 10 分钟触发一次。作为测试,我希望计时器每 10 分钟触发一次,以便我可以测试计时器。
@Stateless
public class TimerTest implements
TimerTestLocal, TimerTestRemote{
@Resource
private TimerService timerService;
private Logger log = Logger.getLogger(TimerTest.class);
private long interval = 1000 * 60 * 10;
private static String TIMER_NAME = "AuditTimer";
public void scheduleTimer() throws NamingException {
// TODO Auto-generated method stub
Calendar cal = Calendar.getInstance();
//cal.set(Calendar.HOUR_OF_DAY, 23);//run at 11pm
//cal.set(Calendar.MINUTE, 00);
//cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm");
log.debug("schedule for: " + sdf.format(cal.getTime()));
timerService.createTimer(cal.getTime(), interval, TIMER_NAME);
}
public void cancelTimer() {
for(Object obj : timerService.getTimers())
{
Timer timer = (Timer)obj;
if(timer.getInfo().equals(TIMER_NAME))
timer.cancel();
}
}
@Timeout
public void timerEvent(Timer timer) {
log.debug("timer fired");
}
}
So is there any way that I can start this timer when the application is deployed? I don't think it's a good idea to put the creation of the Timer in a @PostConstruct method because of class loaders on in the server.
那么有什么方法可以在部署应用程序时启动这个计时器?我认为将 Timer 的创建放在 @PostConstruct 方法中不是一个好主意,因为服务器上有类加载器。
采纳答案by Jesse
The way that I've done timers in the past is to create a context listener in the web.xml to configure the timer.
我过去做计时器的方法是在 web.xml 中创建一个上下文侦听器来配置计时器。
That way you can ensure that it is started with the container, and shut down cleanly when the app is taken down.
这样您就可以确保它与容器一起启动,并在应用程序关闭时干净地关闭。
回答by Mike
I don't know whether using the contextListener to start the timer can work. From this article, how to use EJb 3 timer in a weblogic 10 cluster, it looks like you may run into some problems in weblogic 10.3.2.
不知道使用contextListener启动定时器是否可以。从这篇文章,如何在weblogic 10集群中使用EJb 3 timer,看来你在weblogic 10.3.2中可能会遇到一些问题。
回答by seafoxx
If your project can use jee6 / ejb3.1 there is a much better solution to this problem. http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
如果您的项目可以使用 jee6/ejb3.1,那么这个问题有一个更好的解决方案。 http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
@javax.ejb.Schedule(minute="*/10", hour="*")
public void automaticTimeout() {
logger.info("Automatic timeout occured");
}
By using the new @Schedule annotation you have extensive control about when and how often a timeout method will be called. The big upside: you no longer have to start the timer "from outside".
通过使用新的 @Schedule 注释,您可以广泛控制调用超时方法的时间和频率。最大的好处:您不再需要“从外部”启动计时器。
Oracle writes:
甲骨文写道:
Automatic timers are created by the EJB container when an enterprise bean that contains methods annotated with the @Schedule or @Schedules annotations is deployed. An enterprise bean can have multiple automatic timeout methods, unlike a programmatic timer, which allows only one method annotated with the @Timeout annotation in the enterprise bean class.
当部署包含用@Schedule 或@Schedules 批注批注的方法的企业bean 时,EJB 容器会创建自动计时器。一个企业 bean 可以有多个自动超时方法,这与程序化计时器不同,后者只允许在企业 bean 类中使用 @Timeout 注释来注释一个方法。