第一次写博客,工作一年了,偶尔会遇到一些问题,就想记录下来,如有不对,可以及时联系我修改,谢谢!
在一次工作中,需要用的异步场景,因为项目代码是用springBoot, 所以我们都知道用@Async 注解可以解决,但是这个注解和@Transaction一样
是可能会失效的(具体原因需要了解spring与动态代理)。
异步方法代码:
@Async public void async() throws InterruptedException { //当前线程===第一次:async=======http-nio-8081-exec-1 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); System.out.println(stackTrace[1].getMethodName()+"======="+Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("B-Async end"); }
调用处:
@Override public void test() throws InterruptedException { //不生效 原因: 直接调用相当于 this.async(),而this是当前类,是没有经过 spring的Aop增强的,所以这里必须是代理对象调用才能生效。 async(); //生效 原因: 获取的是当前对象的代理对象,代理对象是被增强过的。 ((AsyncInterfaceImpl) AopContext.currentProxy()).async(); // System.out.println("test end"); }
很明显直接 async();是不生效的,因为当前类不是代理类,
用 ((AsyncInterfaceImpl) AopContext.currentProxy()).async(); 就可以解决, 但是这样写每次都要强转非常麻烦,所以我们决定写一个工具类。
工具类代码:
public class AopUtils { public static <T> T getClassT(Class<T> c){ return c.cast(AopContext.currentProxy()); } }
采用工具类后:
@Override @GetMethod public void test() throws InterruptedException { //不生效 async(); //工具类生效 AsyncInterfaceImpl service = AopUtils.getClassT(this.getClass()); service.async();
// ((AsyncInterfaceImpl) AopContext.currentProxy()).async(); // System.out.println("test end"); }
很明显看到,我们利用泛型,以后再也不用类型转换了,能够直接调用方法。
感谢观看,希望以后有时间自己也能多写点,以免每次工作用完就忘了 ~