Java 服务中的 Spring @Async 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24798695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @Async method inside a Service
提问by Tobia
I have this Service bean with a sync method calling an internal async method:
我有一个带有调用内部异步方法的同步方法的服务 bean:
@Service
public class MyService {
public worker(){
asyncJob();
}
@Async
asyncJob(){
...
}
}
The trouble is that the asyncJob is not really call in async way. I found that this doesn't work because an internal call skips the AOP proxy.
问题是 asyncJob 并不是真正以异步方式调用。我发现这不起作用,因为内部调用跳过了AOP 代理。
So I try to self-referthe bean:
所以我尝试自我引用bean:
@Service
public class MyService {
MyService mySelf;
@Autowired
ApplicationContext cnt;
@PostConstruct
public init(){
mySelf=(MyService)cnt.getBean("myService");
}
public worker(){
mySelf.asyncJob();
}
@Async
asyncJob(){
...
}
}
It fails. Again no async call.
它失败了。再次没有异步调用。
So I tryed to divide itin two beans:
所以我试着把它分成两个豆子:
@Service
public class MyService {
@Autowired
MyAsyncService myAsyncService;
public worker(){
myAsyncService.asyncJob();
}
}
@Service
public class MyAsyncService {
@Async
asyncJob(){
...
}
}
Fails again.
再次失败。
The only working way is to call it from a Controller Bean:
唯一可行的方法是从Controller Bean调用它:
@Controller
public class MyController {
@Autowired
MyAsyncService myAsyncService;
@RequestMapping("/test")
public worker(){
myAsyncService.asyncJob();
}
}
@Service
public class MyAsyncService {
@Async
public asyncJob(){
...
}
}
But in this case it is a service job... why I can not call it from a Service?
但在这种情况下,它是一项服务工作……为什么我不能从服务中调用它?
采纳答案by Tobia
I solved the third method (divide it in two beans) switching Async method modifier to public
我解决了第三种方法(将其分成两个bean)将Async方法修饰符切换为public
@Service
public class MyService {
@Autowired
MyAsyncService myAsyncService;
public worker(){
myAsyncService.asyncJob();
}
}
@Service
public class MyAsyncService {
@Async
public asyncJob(){ // switched to public
...
}
}
回答by jlb
Found a really nice way to solve this (with java8) in the case where you have a lot of various things you want to both sync and async. Instead of creating a separate XXXAsync
service for each 'synchronous' service, create a generic async service wrapper:
找到了一个非常好的方法来解决这个问题(使用 java8),如果你有很多想要同步和异步的东西。不是XXXAsync
为每个“同步”服务创建单独的服务,而是创建一个通用的异步服务包装器:
@Service
public class AsyncService {
@Async
public void run(final Runnable runnable) {
runnable.run();
}
}
and then use it as such:
然后这样使用它:
@Service
public class MyService {
@Autowired
private AsyncService asyncService;
public void refreshAsync() {
asyncService.run(this::refresh);
}
public void refresh() {
// my business logic
}
public void refreshWithParamsAsync(String param1, Integer param2) {
asyncService.run(() -> this.refreshWithParams(param1, param2));
}
public void refreshWithParams(String param1, Integer param2) {
// my business logic with parameters
}
}