Java-第十五部分-源码解读-AOP梳理

139 阅读6分钟

源码解读全文

AOP

  • AOP,面向切面,不修改源代码进行方法增强
  • 通过AbstractAutoProxyCreator后置处理器实现,通过AnnotationAwareAspectJAutoProxyCreator调用
  • 切面Bean只是负责在初始化增强器时,进行信息提取,正常的创建的时候一个普通的Bean对象
  • 过程
  1. 注册AOP后置处理器,准备AOP必要的组件
  2. 获取所有的增强方法,并封装为增强器

准备流程

  • registerBeanPostProcessors(beanFactory);注册Bean后置处理器
  • invokeAwareMethods(beanName, bean);实现了BeanFactoryAware接口,调用setBeanFactory
  • 调用initBeanFactory,初始化BeanFactory
  1. ReflectiveAspectJAdvisorFactory创建增强器
  2. BeanFactoryAspectJAdvisorsBuilderAdapter创建建造者,一个适配器器,连接工厂和增强器工厂
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   super.initBeanFactory(beanFactory);
   if (this.aspectJAdvisorFactory == null) {
      this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
   }
   this.aspectJAdvisorsBuilder =
         new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

初始化流程

  • 当后置处理器准备完成后,在创建之后所有Bean的时候,都会进行干预
  • 在真正创建Bean前,Object bean = resolveBeforeInstantiation(beanName, mbdToUse);给后置处理器一个机会返回自定义的Bean中调用AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation
  • 其中进行判断
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
    //缓存基础类 / 包含 AspectJPointcutAdvisor 增强器的类
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return null;
}

isInfrastructureClass

  • 其中判断Bean是否为切面类
protected boolean isInfrastructureClass(Class<?> beanClass) {
    // 是否实现了`Advice/Pointcut/Advisor/AopInfrastructureBean`
   return (super.isInfrastructureClass(beanClass) || 
         (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass))); //是否有`@Aspect`注解
}

shouldSkip

  • 第一次进,会进行AnnotationAwareAspectJAutoProxyCreator的初始化环节,初始化切面/增强器
  • 是否需要跳过shouldSkip(beanClass, beanName),如果实现了Advisor接口,则为true,是被增强类
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // 获取所有实现了`Advisor`接口的类
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) { 
       //是否包含 AspectJPointcutAdvisor 的增强器
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   // 是否是 isOriginalInstance
   return super.shouldSkip(beanClass, beanName);
}
  • findCandidateAdvisors,找到所有候选增强器
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   List<Advisor> advisors = super.findCandidateAdvisors();
   if (this.aspectJAdvisorsBuilder != null) {
       // 第一次进,不知道切面,创建一个切面建造者
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}
  • this.aspectJAdvisorsBuilder.buildAspectJAdvisors()流程
  1. 获取容器中的所有具体类String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
  2. 判断是否为切面this.advisorFactory.isAspect(beanType),添加到aspectNames
  3. 获取其中的增强方法List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);

构建增强器

  • this.aspectJAdvisorsBuilder.buildAspectJAdvisors()中进行
  • 找到所有切面String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false);
  • 获取增强器List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
  • 获取所有方法getAdvisorMethods(aspectClass)
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
   List<Method> methods = new ArrayList<>();
   // 递归获取所有的方法,并进行过滤
   ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
   if (methods.size() > 1) {
      methods.sort(adviceMethodComparator);
   }
   return methods;
}
  • adviceMethodFilter,过滤掉Pointcut切点
private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
      .and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
  • 看候选的每一个方法是否为增强方法Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      int declarationOrderInAspect, String aspectName) {
   validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    //获取切入点表达式,解析注解内容
   AspectJExpressionPointcut expressionPointcut = getPointcut(
         candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    //没有,则跳过
   if (expressionPointcut == null) {
      return null;
   }
    //进行封装 切点/增强器/切面
   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
  • 切面是单例的放入缓存this.advisorsCache.put(beanName, classAdvisors);

多例,this.aspectFactoryCache.put(beanName, factory);

对Bean的影响

  • Object bean = resolveBeforeInstantiation(beanName, mbdToUse);给后置处理器一个机会返回自定义的Bean中调用AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation

其中返回为null,当配置了AnnotationAwareAspectJAutoProxyCreator中的customTargetSourceCreators,会提前返回处理好的Bean

  • 某一个Bean创建完成后,调用wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);初始化后的后置处理器
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      //配合循环引用的处理,没有被处理过,才进行处理
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
          //AOP增强
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   // 为false,不能进行代理处理
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   // 判断 是否为切面相关的基础类 / 是否包含增强器
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // 如果有切面的方法切入,就创建代理对象
   // 其中需要找合适的增强器 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   //DO_NOT_PROXY - null
   if (specificInterceptors != DO_NOT_PROXY) {
       //缓存已经处理过的Bean
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //创建代理
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }
    // 不需要被AOP增强,进行缓存
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

findEligibleAdvisors

  • 发现可用的增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //获取所有增强器
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   //能不能运用到这个对象
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   // 创建增强器链 添加 ExposeInvocationInterceptor.ADVISOR 方法拦截器
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
       //根据通知类型进行排序,决定执行顺序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}
  • findAdvisorsThatCanApply流程
  1. 遍历所有增强器,并进行类型判断
  2. PointcutAdvisor的类型,获取切点表达式比较器
  3. 遍历目标类的所有方法,正则解析,是否匹配
  • 返回结果 image.png

createProxy

  • 创建代理
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {
   if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
      AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
   }
   ProxyFactory proxyFactory = new ProxyFactory();
   //复制信息 代理的目标类
   proxyFactory.copyFrom(this);
   if (proxyFactory.isProxyTargetClass()) {
      if (Proxy.isProxyClass(beanClass)) {
         for (Class<?> ifc : beanClass.getInterfaces()) {
            proxyFactory.addInterface(ifc);
         }
      }
   }
   else {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
          //计算代理对象的接口
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
    //构建增强器,需要进行判断
    //advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   ClassLoader classLoader = getProxyClassLoader();
   if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
   }
   // 创建代理
   return proxyFactory.getProxy(classLoader);
}
  • 调用createAopProxy,通过哪种方式创建代理
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (!NativeDetector.inNativeImage() &&
         (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      //有接口,有接口,用JDK创建代理
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      //cglib
      return new ObjenesisCglibAopProxy(config);
   }
   else {
       //jdk
      return new JdkDynamicAopProxy(config);
   }
}
  • 最终生成的代理对象,包含真正的执行器 image.png

调用方法

  • 代理对象调用方法,会进入DynamicAdvisedInterceptor中的intercept回调方法
  • 获取目标对象 TargetSource targetSource = this.advised.getTargetSource();
  • 把增强器变为方法拦截器 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);,拦截器真正执行目标方法,拦截器中有invoke,规范每一个增强器的调用方式

将增强器转换为拦截器interceptors.add(adapter.getInterceptor(advisor));

  • 责任链模式,在执行目标方法前后,执行目标方法

cglib执行过程

  • chain为空,直接调用目标方法
retVal = methodProxy.invoke(target, argsToUse);
  • 创建方法执行器MI,cglib中的实现,封装信息,进行执行
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
  • 调用父类ReflectiveMethodInvocationproceed,递归链式调用
  1. ExposeInvocationInterceptor
  2. AspectJAroundAdvice
  3. MethodBeforeAdviceInterceptor
  4. AspectJAfterAdvice
  5. AfterReturningAdviceInterceptor
  6. AspectJAfterThrowingAdvice
public Object proceed() throws Throwable {
   // 有没有到达最后一个
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }
    //获取当前拦截器,实际AOP中的拦截器
   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
         
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
      if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else {
         // Dynamic matching failed.
         // Skip this interceptor and invoke the next in the chain.
         // 跳过当前拦截器
         return proceed();
      }
   }
   else {
      // 调第一个`invoke`,传入方法执行器
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}
  • 处理完所有拦截器,调用invokeJoinpoint,执行目标方法
protected Object invokeJoinpoint() throws Throwable {
   return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

ExposeInvocationInterceptor的invoke

  • 在准备拦截器时添加的
  • 将当前对象方法调用器放入ThreadLocal,方便线程共享,线程共享数据
public Object invoke(MethodInvocation mi) throws Throwable {
   MethodInvocation oldInvocation = invocation.get();
   invocation.set(mi);
   try {
       //调用下一个方法拦截器
      return mi.proceed();
   }
   finally {
      invocation.set(oldInvocation);
   }
}

AspectJAroundAdvice的invoke

  • 用法
@Around("execution(public void com.java.service.UserService.test())")
public void myAround(ProceedingJoinPoint joinPoint) throws Throwable {
    //调用切点,继续执行链路方法
   joinPoint.proceed();
   System.out.println("myAround..");
}
  • 环绕增强
public Object invoke(MethodInvocation mi) throws Throwable {
   if (!(mi instanceof ProxyMethodInvocation)) {
      throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
   }
   //强转成 ProxyMethodInvocation
   ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
   //包装成切点
   ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
   JoinPointMatch jpm = getJoinPointMatch(pmi);
   // 执行方法,增强方法
   return invokeAdviceMethod(pjp, jpm, null, null);
}

MethodBeforeAdviceInterceptor的invoke

public Object invoke(MethodInvocation mi) throws Throwable {
    //先调用前置通知
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
   return mi.proceed();
}

AspectJAfterAdvice的invoke

  • 后置通知,先继续调用,在返回前调用增强方法,有异常时,仍然执行
public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      return mi.proceed();
   }
   finally {
      invokeAdviceMethod(getJoinPointMatch(), null, null);
   }
}

AfterReturningAdviceInterceptor的invoke

  • 返回通知拦截器,发生异常时,会被跳过
public Object invoke(MethodInvocation mi) throws Throwable {
    //继续执行
   Object retVal = mi.proceed();
   //获得返回值
   this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
   return retVal;
}

AspectJAfterThrowingAdvice的invoke

  • 异常通知拦截器
public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      return mi.proceed();
   }
   catch (Throwable ex) {
       //处理异常
      if (shouldInvokeOnThrowing(ex)) {
         invokeAdviceMethod(getJoinPointMatch(), null, ex);
      }
      throw ex;
   }
}

JDK代理流程

  • JdkDynamicAopProxyinvoke
  • 获取增强链路,并转化为方法拦截器List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  • 执行调用,一样递归链式处理的流程
MethodInvocation invocation =
      new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();