4

我有一个方法需要每天 07:00 执行。为此,我使用该方法创建了一个 bean 并使用@Scheduled(cron="0 0 7 * * ?"). 在这个 bean 中,我创建了一个main函数 - 它将初始化 spring 上下文,获取 bean 并调用方法(至少是第一次),如下所示:

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(args[0]);
    SchedulerService schedulerService = context.getBean(SchedulerService.class);
    schedulerService.myMethod();
}

这工作得很好 - 但只有一次。我想我明白为什么 - 这是因为main线程结束 - 弹簧上下文也是如此,所以即myMethod使用它进行注释@Scheduled也不会起作用。

我想到了一种方法来传递这个——意思是不要让main线程死掉,也许是这样的:

while (true){
   Thread.currentThread().sleep(500);
}

我认为,这就是应用程序上下文将保持不变的方式,我的 bean 也是如此。

我对吗?

有没有更好的方法来解决这个问题?

我正在使用弹簧 3.1.2。

谢谢。

4

2 回答 2

4

主线程应保持活动状态,直到任何非守护线程处于活动状态。如果你<task:annotation-driven/>的应用程序中有一个标签,那么 Spring 应该为你启动一个带有一小部分非守护线程池的执行程序,并且主应用程序不应该终止。

您唯一需要做的就是注册一个关闭挂钩以确保在 VM 结束时进行清理。

context.registerShutdownHook()

于 2012-08-29T20:00:40.277 回答
1

join 方法非常适合:

    try {
        Thread.currentThread().join();
    } catch (InterruptedException e) {
        logger.warn("Interrupted", e);
    }

或者,这是老式的等待方法:

    final Object sync = new Object();
    synchronized (sync) {
        try {
            sync.wait();
        } catch (InterruptedException e) {
            logger.warn("Interrupted", e);
        }
    }
于 2012-08-29T21:08:53.143 回答