繁体   English   中英

EJB 3.x中@Schedule方法的动态参数

[英]Dynamic parameters for @Schedule method in an EJB 3.x

我是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
    }
}

在这里,我们希望从数据库中获取参数,因此它们每个月都会更改。 对此有什么清洁解决方案?

@Singleton
@Startup
public class ScheduleTimerService {

    @Resource private TimerService timerService;

    public void setTimerService(TimerService timerService) {this.timerService = timerService; }

    @PostConstruct
    private void postConstruct() {
        timerService.createCalendarTimer(createSchedule());
    }

    @Timeout
    public void timerTimeout(Timer timer) {
           Add your code here to be called when scheduling is reached...
           in this example: 01h:30m every day ;-)
    }

    private ScheduleExpression createSchedule(){

        ScheduleExpression expression = new ScheduleExpression();
        expression.dayOfWeek("Sun,Mon,Tue,Wed,Thu,Fri,Sat");    
        expression.hour("01");
        expression.minute("30");

        return expression;
    }
}

不,@ @Schedule没有解决方案,因为注释属性通常应该是编译时常量。

当需要更大的灵活性时,可以使用编程定时器 此外,必须实现轮询数据库以更改配置并删除现有和创建新计时器。

那么您需要创建两个调度程序一个调度程序将运行以从基于您可以创建其他调度程序的数据库更新数据。

但是对于这个需要做一些程序化的。 您也可以看到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!");
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM