我正在使用Spring应用程序从不同的API下载数据。为此,我需要一个类Fetcher,它与API交互以获取所需的数据。这个类的一个要求是它必须有一个方法来启动提取和一个方法来停止它。此外,它必须异步下载所有内容,因为用户必须能够在获取数据时与仪表板进行交互。
实现这一目标的最佳方法是什么?我一直在阅读关于任务执行器和Spring的不同注释来安排任务并异步执行它们,但这个解决方案似乎并没有解决我的问题。
答案 0 :(得分:3)
异步任务执行就是你所追求的,从Spring 3.0开始,你可以使用注释直接在你想要运行的方法上实现这一点。
根据您是否有兴趣从异步过程中获取结果,有两种实现方法:
@Async
public Future<ReturnPOJO> asyncTaskWithReturn(){
//..
return new AsyncResult<ReturnPOJO>(yourReturnPOJOInstance);
}
与否:
@Async
public void asyncTaskNoReturn() {
//..
}
在前一种方法中,yourReturnPOJOInstance对象实例传达的计算结果存储在org.springframework.scheduling.annotation.AsyncResult<V>
的实例中,该实例返回实现调用者可用于检索结果的java.util.concurrent.Future<V>
。稍后计算。
要在Spring中激活上述功能,您必须添加XML配置文件:
<task: annotation-driven />
以及所需的任务命名空间。
答案 1 :(得分:1)
最简单的方法是使用Thread
类。您提供了一个Runnable
对象,该对象在run()
方法中执行提取功能,并且在启动Thread时,它会在单独的执行线程中调用run
方法。
这样的事情:
public class Fetcher implements Runnable{
public void run(){
//do fetching stuff
}
}
//in your code
Thread fetchThread = new Thread(new Fetcher());
fetchThread.start();
现在,如果你想取消,你可以通过几种方式做到这一点。最简单的(尽管最暴力和最不可取的方法是打断线程:
fetchThread.interrupt();
执行此操作的正确方法是在Fetcher
类中实现逻辑,该逻辑定期检查变量以查看它是否应该停止执行任何正在执行的操作。
编辑关于让Spring自动运行它的问题,如果你想让它定期运行,你需要使用像Quartz这样的调度框架。但是,如果您只想让它运行一次,您可以使用@PostConstruct
注释。使用@PostConstruct
注释的方法将在创建bean之后执行。所以你可以做这样的事情
@Service
public class Fetcher implements Runnable{
public void run(){
//do stuff
}
@PostConstruct
public void goDoIt(){
Thread trd = new Thread(this);
trd.start();
}
}
编辑2 我实际上并不知道这一点,但如果你还没有,请查看Spring documentation中的@Async
讨论。也可能是你想做的事。
答案 2 :(得分:0)
您可能只需要某些方法在单独的线程上运行,而不是整个类。如果是这样,@Async
注释非常简单易用。
只需将其添加到您想要异步运行的任何方法,您也可以使用它的返回类型的方法,这要归功于Java的Future
库。