我对Spring的@Async
注释以及如何正确使用它有疑问。假设我有这些方法:
@Async
public void test(String param1) {
test2(param1, null);
}
@Async
public void test2(String param1, String param2) {
test3(param1, param2, null);
}
@Async
public void test3(String param1, String param2, String param3) {
// do some heavy work
}
我是否需要在所有三种方法上使用@Async
才能异步调用它,或者它只能在test3
上实际完成这项工作吗?
答案 0 :(得分:3)
你确实只需要一种方法。仅仅因为在使用第一个@Async
- 方法启动新线程之后,它与调用方法是异步的。
但这对你意味着什么,在很大程度上取决于你的例子应该说明的内容:
1)因此,在您通过{{1}调用@Async
和test1(String param1)
时,test2
的{{1}}就足够了}}
test3
请注意,方法2和3是私有的
2)但是,如果您的示例用于说明默认参数(Method chaining)的方法重载模式,则更复杂。然后,您需要在执行真实内容的方法中使用test1
注释。因为您只想以异步方式执行实际执行,而不是每个链接步骤执行一次异步调用。
@Async
public void test1(String param1) {
test2(param1, null);
}
private void test2(String param1, String param2) {
test3(param1, param2, null);
}
private void test3(String param1, String param2, String param3) {
// do something
}
请注意,所有方法仅以@Async
命名(方法链式模式)
问题是,如果通过public void test(String param1) {
test(param1, null);
}
public void test(String param1, String param2) {
//this invocation runs async only when real AspectJ is used
test(param1, param2, null);
}
@Async
public void test(String param1, String param2, String param3) {
// do something
}
调用它,那么Spring(没有真正的AspectJ加载或编译时编织)将不会运行方法async()(参见{ {3}})
答案 1 :(得分:2)
我认为@Ralph涵盖了您的担忧。
但问题的名称是“如何在Spring中正确使用@Async”,我不得不提到:
您应该始终在Spring上下文中更改(或至少考虑更改)默认任务执行程序,或使用自定义任务执行程序。
默认情况下,SimpleAsyncTaskExecutor将用于处理异步 方法调用。
注意:此实现不会重用线程!请考虑使用线程池TaskExecutor实现,尤其是 执行大量短期任务。
答案 2 :(得分:0)
仅在第三种方法@Async
上使用test3
是不够的,因为本地调用导致该对象未被代理,并且只有代理对象(从容器中拾取,例如使用@Autowired
)异步调用
同时查看here