Spring AOP调用本类方法不生效(2)

131 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

public void setBeanFactory(BeanFactory beanFactory) {
   super.setBeanFactory(beanFactory);

   AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
   if (this.asyncAnnotationType != null) {
      advisor.setAsyncAnnotationType(this.asyncAnnotationType);
   }
   advisor.setBeanFactory(beanFactory);
   this.advisor = advisor;
}

ProxyAsyncConfiguration构建AsyncAnnotationBeanPostProcessor时,注解的这个参数值被注入到其内部属性AsyncAnnotationType,并在 setBeanFactory 方法中被注入进AsyncAnnotationAdvisor) ps: @EnableAsync 可以通过内部属性annotation 来指定注自定义解类型 。

2.2.4、AsyncAnnotationAdvisor

AsyncAnnotationAdvisor 的构造函数 在这个Advisor的构造函数中明确构建了advice -> AnnotationAsyncExecutionInterceptor 与 pointcut,并指定切面注解类型是asyncAnnotationTypes(默认为@Async)

      @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {

   Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
   //在用户自定义的拦截注解上额外加入Async到需要拦截的注解集合
   asyncAnnotationTypes.add(Async.class);
   try {
      asyncAnnotationTypes.add((Class<? extends Annotation>)
            ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
   }
   catch (ClassNotFoundException ex) {
      // If EJB 3.1 API not present, simply ignore.
   }
   this.advice = buildAdvice(executor, exceptionHandler);
   this.pointcut = buildPointcut(asyncAnnotationTypes);
}

2.2.5、AnnotationAsyncExecutionInterceptor拦截器

      @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {

   AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
   interceptor.configure(executor, exceptionHandler);
   return interceptor;
}

没有实现AsyncConfigurer类,则使用默认值

      @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
   //如果defaultExecutor为null,也就是没有指定Executor,设置默认的SimpleAsyncTaskExecutor(在子类AsyncExecutionInterceptor中重载getDefaultExecutor方法)
   this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
   //如果没有指定exceptionHandler默认SimpleAsyncUncaughtExceptionHandler
   this.exceptionHandler = new SingletonSupplier<>(exceptionHandler, SimpleAsyncUncaughtExceptionHandler::new);
}

其父类AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor。 首先我们来看下MethodInterceptor的定义, 可见 MethodInterceptor就是所谓的Advice

public interface MethodInterceptor extends Interceptor {

   /**
    * Implement this method to perform extra treatments before and
    * after the invocation. Polite implementations would certainly
    * like to invoke {@link Joinpoint#proceed()}.
    * @param invocation the method invocation joinpoint
    * @return the result of the call to {@link Joinpoint#proceed()};
    * might be intercepted by the interceptor
    * @throws Throwable if the interceptors or the target object
    * throws an exception
    */
   Object invoke(MethodInvocation invocation) throws Throwable;

}

AsyncExecutionAspectSupport.invoke 就是一个切面在命中时的具体处理逻辑。

PS: 比较重要的是如何选择异步处理的线程池AsyncTaskExecutor过程

determineAsyncExecutor方法** 1、以方法作为区分从beanFactory中去查找,名称优先为方法注解@Async指定异步处理线程池对象Qualifier名 2、其次为默认实现的线程池,名称为“taskExecutor”,类型为 Executor.class

   AsyncTaskExecutor executor = this.executors.get(method);
   if (executor == null) {
      Executor targetExecutor;
      String qualifier = getExecutorQualifier(method);
      if (StringUtils.hasLength(qualifier)) {
         targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
      }
      else {
         targetExecutor = this.defaultExecutor.get();
      }
      if (targetExecutor == null) {
         return null;
      }
      executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
            (AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
      this.executors.put(method, executor);
   }
   return executor;
}

进行方法的异步调用——使用线程池

protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
   //使用的java8 的新的Future相关API,CompletableFuture来完成
   if (CompletableFuture.class.isAssignableFrom(returnType)) {
      return CompletableFuture.supplyAsync(() -> {
         try {
            return task.call();
         }
         catch (Throwable ex) {
            throw new CompletionException(ex);
         }
      }, executor);
   }
   else if (ListenableFuture.class.isAssignableFrom(returnType)) {
      //提交任务
      return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
   }
   else if (Future.class.isAssignableFrom(returnType)) {
      //提交任务
      return executor.submit(task);
   }
   else {
      //提交任务
      executor.submit(task);
      return null;
   }
}