I have this Service bean with a sync method calling an internal async method:
@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.
So I try to self-refer the 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 it in 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
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?
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:and then use it as such:
I solved the third method (divide it in two beans) switching Async method modifier to public