在开发过程中,尽量会将比较耗时且并不会影响请求的响应结果的业务放在异步线程池中进行处理,那么到时什么任务在执行的时候会创建单独的线程进行处理呢?我们可以在对应的业务方法上打上自定义的注解,再利用AOP去捕捉这个注解,就可以利用环绕通知的特性进行异步的设置。
一、先说说线程的几种创建方式(简要列举)
二、再聊一聊spring自带的@Async注解实现异步任务的方法
三、那么就来设计一下怎么使用自定义的注解实现异步任务
首先我们写一个注解:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAsync {
//规定value是异步开关
boolean value() default false;
}
我们让注解中的value的值定为布尔类型,从而根据它的真假来决定异步线程的创建。
我们将它打在业务类的方法上:
@MyAsync(value = true)
public void deleteDb(){
/*service code......*/
System.out.println("delete------>数据删除");
}
然后我们利用AOP扫描这个注解:
Aspect
@Component
public class AopUtils {
@Around(value = "@annotation(com.example.aop.Aop异步.MyAsync)")
public void listenMyAsync(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
MyAsync annotation = method.getAnnotation(MyAsync.class);
boolean value = annotation.value();
if (value)
new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
joinPoint.proceed();
}
}).start();
else
joinPoint.proceed();
}
}
我们可以看到利用Around寻找执行的线程中某个含有注解的方法栈,捕捉到之后就可以获得对应的连接点对象了。
利用可通过连接点对象ProcedJoinPoint的getSignture方法获取签名,可以将签名强制转化成方法签名MethdSignture类型,从而利用该类型的getMethod方法获取方法本身,接下来就可以获取方法的注解,利用注解的属性直接获取value的真假,从而决定方法通过的方式是同步的还是异步的。(源码利用到反射机制)。