记录一下Spring同类异步调用
Spring默认情况下对于@Async
和@Transactional
等方法调用只在代理类的情况下有效,例如A类调用B类的加了注解的xxx方法可以,但是B类的其他方法调用B类的加了注解的xxx方法就不行,不能拦截到并开启事务或者异步。
配置方式
关键代码:@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
,如果Bean没有实现接口,要配置proxyTargetClass=true
。要从AopContext
中获取到代理对象,必须exposeProxy=true
。
@Configuration
@EnableAsync
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
public class DefaultAsyncConfig {}
代理执行
要使异步或者事务代码生效,需要获取到代理对象执行:
TestService currentProxy = (TestService) AopContext.currentProxy();
测试代码
调用TestService#testSync方法:
@Component
public class TestService {
private static final Logger logger = LoggerFactory.getLogger(TestService.class);
@Async
public void testAsync(){
logger.info("Async Thread Name: {}", Thread.currentThread().getName());
}
public void testSync(){
logger.info("Sync Thread Name: {}", Thread.currentThread().getName());
this.testAsync();
TestService currentProxy = (TestService) AopContext.currentProxy();
currentProxy.testAsync();
}
}
执行结果
没有通过代理调用的时候异步没有生效,直接是http的线程,并没有异步成功。
2021-03-09 10:42:08.125 INFO 9912 --- [nio-9091-exec-5] c.c.m.p.h.service.connect.TestService : Sync Thread Name: http-nio-9091-exec-5
2021-03-09 10:42:08.126 INFO 9912 --- [nio-9091-exec-5] c.c.m.p.h.service.connect.TestService : Async Thread Name: http-nio-9091-exec-5
2021-03-09 10:42:08.127 INFO 9912 --- [service-async-4] c.c.m.p.h.service.connect.TestService : Async Thread Name: cloud-service-async-4