问题
I have a method which needs to be executed every day at 07:00.
For that matter I created a bean with the method and annotated it with @Scheduled(cron="0 0 7 * * ?")
.
In this bean I crated a main
function - which will initialize the spring context, get the bean and invoke the method ( at least for the first time ), like this:
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(args[0]);
SchedulerService schedulerService = context.getBean(SchedulerService.class);
schedulerService.myMethod();
}
This works just fine - but just once.
I think I understand why - It's because the main
thread ends - and so is the spring context so even though myMethod
is annotated with @Scheduled
it wont work.
I thought of a way to pass this - meaning don't let the main
thread die, perhaps like this:
while (true){
Thread.currentThread().sleep(500);
}
That's how, I think, the application context will remain and so is my bean.
Am I right?
Is there a better way to solve this?
I'm using spring 3.1.2.
Thanks.
回答1:
The main thread should stay active until any non-daemon threads are alive. If you have a <task:annotation-driven/>
tag in your application then Spring should start up a executor with a small pool of non-daemon threads for you and the main application should not terminate.
The only thing that you will need to do is to register a shutdown hook also to ensure a cleanup when the VM ends.
context.registerShutdownHook()
回答2:
The join method is ideal for this:
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
logger.warn("Interrupted", e);
}
Alternatively, here's the old school wait method:
final Object sync = new Object();
synchronized (sync) {
try {
sync.wait();
} catch (InterruptedException e) {
logger.warn("Interrupted", e);
}
}
来源:https://stackoverflow.com/questions/12176923/scheduled-method-in-a-standalone-application-in-spring