EJB 3.x中@Schedule方法的动态参数
我是J2EE6中@Schedule注释的新手
我想使用带有Glassfish 3.1的EJB 3.x运行一个作业。
javax.ejb.Schedule对我们来说似乎是一个不错的选择,因此我们可以将自定义时间视为:
@Singleton public class CustomTimer { @EJB SettingsFacade settingsFacade; @Schedule(second="someSecondParameter", minute="someMinuteParameter",hour="someHourParameter", persistent=false) public void executeTimer(){ //Code executing something against database using the settingsFacade } }
在这里,我们希望从数据库中获取参数,因此它们每个月都会更改。 任何干净的解决方案?
不,@ @Schedule
没有解决方案,因为注释属性通常应该是编译时常量。
当需要更大的灵活性时,可以使用编程定时器 。 此外,还必须实现轮询数据库以更改配置并删除现有和创建新计时器。
@辛格尔顿 @启动 public class ScheduleTimerService { @Resource私有TimerService timerService; public void setTimerService(TimerService timerService){this.timerService = timerService; } @PostConstruct private void postConstruct(){ timerService.createCalendarTimer(createSchedule()); } @超时 public void timerTimeout(Timer timer){ 在此处添加您的代码,以便在达到调度时调用... 在这个例子中:每天01h:30m ;-) } private ScheduleExpression createSchedule(){ ScheduleExpression表达式= new ScheduleExpression(); expression.dayOfWeek( “周日,周一,周二,周三,周四,周五,周六”); expression.hour( “01”); expression.minute( “30”); 回归表达; } }
那么您需要创建两个调度程序一个调度程序将运行以从基于您可以创建其他调度程序的数据库更新数据。
但是对于这个需要做一些程序化的。 您也可以看到EJB计时器,它们在这种情况下可以帮助您。 这也是基于注释的。
有一种简单的方法可以做到这一点。 我希望每天都能调用一个流程,但是工作本身应该在同一天随机完成。 我设法通过在调用EJB计时器服务之后添加一个简单的线程工作程序来运行。 那天我会在那个时间里让它睡觉一段时间。
以下代码是每1分钟唤醒并等待线程完成的服务示例。
@Schedule(minute = "*/1", hour = "*", persistent = false) public void runEveryMinute() throws InterruptedException { log.log(Level.INFO, "Scheduling for every minute .. now it's: " + new Date().toString()); // Delay, in milliseconds before we interrupt adding a follower thread //we can therefore garantee that it runs every day long patience = 1000 * 5; threadMessage("Starting forever alone no more thread"); long startTime = System.currentTimeMillis(); Thread t = new Thread(new MessageLoop()); t.start(); threadMessage("Waiting for new thread to finish"); // loop until MessageLoop thread exits while (t.isAlive()) { threadMessage("Still waiting..."); // Wait maximum of 1 second for MessageLoop thread to finish. t.join(1000); if (((System.currentTimeMillis() - startTime) > patience) && t.isAlive()) { threadMessage("Tired of waiting! Adding new followers now!"); t.interrupt(); // Shouldn't be long now -- wait indefinitely t.join(); } } threadMessage("Finally! You are not alone anymore!"); } // Display a message, preceded by // the name of the current thread static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s%n", threadName, message); } private static class MessageLoop implements Runnable { public void run() { String importantInfo[] = { "A kid will eat ivy too" }; try { for (int i = 0; i < importantInfo.length; i++) { // Pause for 4 seconds int max = 10; int min = 2; int randomTimer = 0 + (int) (Math.random() * ((max - min) + 1)); Thread.sleep(randomTimer * 1000); // Print a message threadMessage(importantInfo[i]); } } catch (InterruptedException e) { threadMessage("Patience is not a virtue! Thread stopping for now!"); } } }