如何手写一个@Async异步注解
- 一、自定义注解
- 二、编写AOP切面类
- 三、编写测试类
- 四、总结
一、自定义注解
自定义一个@MyAsync注解,可以照抄@Async
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAsync {
}
二、编写AOP切面类
@Aspect
@Component
public class MyAsyncAop {
@Around(value = "@annotation(org.sang.annotation.MyAsync)")
public Object around(ProceedingJoinPoint joinPoint) {
try {
System.out.println("环绕通知开始执行--");
new Thread(() -> {
try {
joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}).start();
System.out.println("环绕通知结束执行--");
} catch (Exception e) {
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
}
三、编写测试类
controller类:
@RequestMapping("/mysync")
public String mysync(){
System.out.println("-------------<1>--------------");
this.userService.asnycLog();
System.out.println("-------------<3>--------------");
return "success";
}
service类:
@MyAsync
public void asnycLog() {
try {
System.out.println("目标方法开始执行,正在阻塞3s----");
Thread.sleep(3000);
System.out.println("-------------<2>--------------");
}catch (Exception e){
}
}
本地访问:
打印结果如下:
-------------<1>--------------
环绕通知开始执行--
环绕通知结束执行--
-------------<3>--------------
目标方法开始执行,正在阻塞3s----
-------------<2>--------------
四、总结
从以上打印日志可以看出,从controller调用service的asnycLog()方法时,由于asnycLog()方法上有 @MyAsync注解,而 @MyAsync注解又在aop中有定义环绕通知,故另起了一个子线程执行,故不需要等待主线程执行,也就实现了异步的执行。所以主线程执行完成,子线程最后执行完成,通过 @MyAsync注解的方法执行程序都是异步执行的了。