spring 源码解析之 AOP(八)

上一篇分享了,spring 中bean实例的循环依赖,今天开始分享解析AOP 源码。

1、首先从源码中AOP 的入口方法开始, AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory  类中的方法如下:

try {
   // IOC 依赖注入的核心方法
   populateBean(beanName, mbd, instanceWrapper);

   //bean 实例化和Ioc依赖注入完以后的调用,这里就是AOP 的入口,点击进入 
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      //调用Aware方法
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //对类中某些特殊方法的调用,比如@PostConstruct,Aware接口
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      //InitializingBean接口,afterPropertiesSet,init-method属性调用
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      //这里可能生出代理实例,是aop的核心入口,点击进入-->
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

来到这个方法:

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {//获取所有的BeanPostProcessors,进行遍历
//这是一个 BeanPostProcessor 接口的埋点运用,进入后选择实现类-->
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

2、进入接口后ctrl+t  显示多个实现类:

  很明显我们进入 AbstractAutoProxyCreator  类,进入的原因如下:

因为AbstractAutoProxyCreator最终是实现了InstantiationAwareBeanPostProcessor接口,因此,resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法中的代码ibp.postProcessBeforeInstantiation(beanClass, beanName)方法循环调用最终可以调用的是AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法完成的AOP相关横切逻辑的加载与解析的。SPI思想关注一下,里面实例化了一些重要的实例:

 

为什么会调用到这里,有个重要的注解需要添加,否则Debug不会走到这里,注解配置如下:

import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @Author nandao
 * Date 2022/7/12 14:09
 * Version 1.0
 */
@Component
//@EnableAspectJAutoProxy(proxyTargetClass = false,exposeProxy = true)
@EnableAspectJAutoProxy //核心注解
public class AopConfig {
}

参考AOP实现原理:核心介绍该注解的原理。

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) {
         return wrapIfNecessary(bean, beanName, cacheKey);//核心方法在这,点击进入-->
      }
   }
   return bean;
}

来到:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   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;
   }

   //该方法去寻找advisor 切面,如果这个bean有advice的话,就创建当前bean的代理,点击进入-->
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   //如果有切面,则生成该bean的代理
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //把被代理对象bean实例封装到SingletonTargetSource对象中
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

业务伪代码测试

package com.enjoy.jack.aop.aspectj;

import com.enjoy.jack.annotation.EasyCache;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

@Component
@Aspect
public class AspectAnnotation {

    @Pointcut(value = "execution(public * com.enjoy.jack.service.*.*(..)) && args(a)",argNames = "a")
    public void pc2(List a){}

    @Pointcut(value = "execution(public * com.enjoy.jack.service.*.*(..))")
    public void pc1(){}

    @Before("pc1()")
    public void Abefore13() {
        MethodInvocation methodInvocation = ExposeInvocationInterceptor.currentInvocation();
        Method method = methodInvocation.getMethod();
        boolean annotationPresent = method.isAnnotationPresent(EasyCache.class);
        System.out.println("==============AspectAnnotation Abefore13=========" + annotationPresent);
    }

    @Before("pc1()")
    public void before13() {
        MethodInvocation methodInvocation = ExposeInvocationInterceptor.currentInvocation();
        System.out.println("==============AspectAnnotation before13=========");

    }

    @Before("pc1()")
    public void before132() {
        System.out.println("==============AspectAnnotation before132=========");

    }

    @Before("pc1()")
    public void before1() {
        System.out.println("==============AspectAnnotation before1=========");

    }

    @Before(value = "pc1()",argNames = "joinPoint")
    public void before2(JoinPoint joinPoint) {
        System.out.println("==============AspectAnnotation before2=========");

    }

    @After(value = "pc1()")
    public void AAfter() {
        System.out.println("==============AspectAnnotation AAfter=========");

    }

    @Around(value = "pc2(a)",argNames = "a")
    public Object around(ProceedingJoinPoint joinPoint, List a) throws Throwable {
        System.out.println("==============AspectAnnotation around前置通知=========");
        Object result = joinPoint.proceed();
        System.out.println("==============AspectAnnotation around后置通知=========");

        return result;
    }

    @Around(value = "pc1()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("==============AspectAnnotation around前置通知=========");
        Object result = joinPoint.proceed();
        System.out.println("==============AspectAnnotation around后置通知=========");

        return result;
    }

    @AfterReturning(value = "pc1()",returning = "retVal")
    public void afterReturning(JoinPoint joinPoint, Object retVal) {
        System.out.println("==============AspectAnnotation 后置通知  拿返回值=========" + retVal);
    }

    @AfterThrowing(value = "pc1()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println("AspectAnnotation 异常通知  拿异常=========" + e);
    }
}

 断点走到

继续:

3、进入  AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator  的  getAdvicesAndAdvisorsForBean 方法:

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

   //寻找到合格的切面,收集起来,点击进入-->
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

来到-->

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //找到候选的切面,其实就是一个寻找有@Aspectj 和相关 注解的过程,把工程中所有有这个注解的类封装成Advisor返回,点击进入-->
   List<Advisor> candidateAdvisors = findCandidateAdvisors();

   //判断上面收集的切面是否作用在当前  beanClass 上面(即是否在:pointcut 的表达式目录里),就是一个匹配过程。把作用在当前beanClass 上面的 Advisor 的集合返回到上游,等待创建代理类
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   //针对@Aspect注解切面添加了一个默认的切面 DefaultPointcutAdvisor
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      //对有@Order@Priority进行排序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

4、ctrl+t 显示:很明显 进入 AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator 类的

进入

@Override
protected List<Advisor> findCandidateAdvisors() {
   //找到所有的Advisor
   // Add all the Spring advisors found according to superclass rules.
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   //这里开始创建候选的切面, 对@Aspect注解的类进行处理,点击进入-->
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

5、来到  BeanFactoryAspectJAdvisorsBuilder

public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            //获取spring容器中的所有bean的名称BeanName,并遍历循环
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // We must be careful not to instantiate beans eagerly as in this case they
               // would be cached by the Spring container but would not have been weaved.
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               //判断类上是否有@Aspect注解,如果有,该类就很可能有切面
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

                     //创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);

                     //创建并获取切面advisor对象,点击进入-->
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // Per target or per this.
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }

   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

生成后有个映射关系保存

 6、ctrl+T 进入  ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable 类的 getAdvisors 方法:

@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
   //从工厂中获取有@Aspect注解的类Class
   Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   //从工厂中获取有@Aspect注解的类的名称
   String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   validate(aspectClass);

   //创建工厂的装饰类,获取实例只会获取一次
   // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
   // so that it will only instantiate once.
   MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
         new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

   List<Advisor> advisors = new ArrayList<>();

   //这里循环没有@Pointcut注解的方法
   for (Method method : getAdvisorMethods(aspectClass)) {

      //重点分析看看 ,点击进入--->
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   // If it's a per target aspect, emit the dummy instantiating aspect.
   if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
   }

   //判断属性上是否有引介注解
   // Find introduction fields.
   for (Field field : aspectClass.getDeclaredFields()) {
      //判断属性上是否有DeclareParents注解,如果有返回切面
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   return advisors;
}

点击getAdvisorMethods(aspectClass) 方法,获取后有个排序的过程,基于两个原则

private List<Method> getAdvisorMethods(Class<?> aspectClass) {
		final List<Method> methods = new ArrayList<>();
		ReflectionUtils.doWithMethods(aspectClass, method -> {
			// Exclude pointcuts
			if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
				methods.add(method);
			}
		}, ReflectionUtils.USER_DECLARED_METHODS);
		if (methods.size() > 1) {
			//按照注解先后顺序+自然顺序排序
			methods.sort(METHOD_COMPARATOR);
		}
		return methods;
	}

 点击 METHOD_COMPARATOR,进入  ReflectiveAspectJAdvisorFactory 看到初始化好的数据

private static final Comparator<Method> METHOD_COMPARATOR;

	static {
		// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
		// an @After advice method will actually be invoked after @AfterReturning and
		// @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
		// invokes proceed() in a `try` block and only invokes the @After advice method
		// in a corresponding `finally` block.
        //先按照注解的顺序排序
		Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
				new InstanceComparator<>(
						Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
				(Converter<Method, Annotation>) method -> {
					AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
					return (ann != null ? ann.getAnnotation() : null);
				});
		Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
        //按照自然的排序,比如before1、before12、cbefore等等,下面有示例证明
		METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
	}

测试参数演示证明

然后返回来到 getAdvisor 方法:

@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      int declarationOrderInAspect, String aspectName) {

   validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

   //获取pointCut对象,最重要的是从注解中获取表达式,即需要代理增强的类所在的目录,点击进入-->
   AspectJExpressionPointcut expressionPointcut = getPointcut(
         candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
   if (expressionPointcut == null) {
      return null;
   }

   //创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
   //这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod,点击-->
   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

测试断点接口,对应业务接口

 来到getPointcut 方法:

@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
   //从候选的增强方法里面 candidateAdviceMethod  找有有注解
   //Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
   //并把注解信息封装成AspectJAnnotation对象,点击进入-->
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }

   //创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
   AspectJExpressionPointcut ajexp =
         new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
   ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
   if (this.beanFactory != null) {
      ajexp.setBeanFactory(this.beanFactory);
   }
   return ajexp;
}

测试如图:

 7、进入  AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory  类中的

findAspectJAnnotationOnMethod 方法:

@SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
   for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
      //遍历Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
      //找到method方法里对应的注解(比如:@Around),然后把注解里面的信息封装成AspectJAnnotation对象返回,当然只会是一个对象
      AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
      if (foundAnnotation != null) {
         return foundAnnotation;
      }
   }
   return null;
}

点击 ASPECTJ_ANNOTATION_CLASSES 查看

private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
			Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};

来到:findAnnotation方法

@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
   //找的规则就是找注解的父注解,递归的方式去找,直到找到目标注解为止
   A result = AnnotationUtils.findAnnotation(method, toLookFor);
   if (result != null) {
      //把注解里面的信息解析出来,然后包装成AspectJAnnotation对象
      return new AspectJAnnotation<>(result);
   }
   else {
      return null;
   }
}

点击 AnnotationUtils.findAnnotation(method, toLookFor);

@Nullable
	public static <A extends Annotation> A findAnnotation(Method method, @Nullable Class<A> annotationType) {
		if (annotationType == null) {
			return null;
		}

		// Shortcut: directly present on the element, with no merging needed?
		if (AnnotationFilter.PLAIN.matches(annotationType) ||
				AnnotationsScanner.hasPlainJavaAnnotationsOnly(method)) {
			return method.getDeclaredAnnotation(annotationType);
		}

		// Exhaustive retrieval of merged annotations...
		return MergedAnnotations.from(method, SearchStrategy.TYPE_HIERARCHY, RepeatableContainers.none())
				.get(annotationType).withNonMergedAttributes()
				.synthesize(MergedAnnotation::isPresent).orElse(null);
	}

测试首次遍历,发现注解不一致,返回空

 遍历第二个注解:两者一致,会返回AspectJAnnotation<?>对象

 请看,这里就返回一个代理对象:

 返回生成 new AspectJAnnotation<>(result) 对象

    public AspectJAnnotation(A annotation) {
			this.annotation = annotation;
			this.annotationType = determineAnnotationType(annotation);
			try {
				//解析注解上面的表达式,如@Around("pc1()"),获取到pc1()值
				//@AfterReturning(pointcut = "execution(public * com.xiangxue.jack.service.*.*(..))")
				this.pointcutExpression = resolveExpression(annotation);
				//获取注解上的参数,比如@Around(value = "pc2(a)",argNames = "a") 上的 argNames = "a"
				Object argNames = AnnotationUtils.getValue(annotation, "argNames");
				this.argumentNames = (argNames instanceof String ? (String) argNames : "");
			}
			catch (Exception ex) {
				throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
			}
		}

测试进入,点击 determineAnnotationType(annotation);

查看 annotationTypeMap 集合,初始化的数据

点击 resolveExpression(annotation);接口返回值

 8、回到上面结果如下:

继续走

 返回 点击 InstantiationModelAwarePointcutAdvisorImpl  对象实现类的构造方法,InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
      Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

   this.declaredPointcut = declaredPointcut;
   this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
   this.methodName = aspectJAdviceMethod.getName();
   this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
   this.aspectJAdviceMethod = aspectJAdviceMethod;
   this.aspectJAdvisorFactory = aspectJAdvisorFactory;
   this.aspectInstanceFactory = aspectInstanceFactory;
   this.declarationOrder = declarationOrder;
   this.aspectName = aspectName;

   if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      // Static part of the pointcut is a lazy type.
      Pointcut preInstantiationPointcut = Pointcuts.union(
            aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

      // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
      // If it's not a dynamic pointcut, it may be optimized out
      // by the Spring AOP infrastructure after the first evaluation.
      this.pointcut = new PerTargetInstantiationModelPointcut(
            this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
      this.lazy = true;
   }
   else {
      // A singleton aspect.
      this.pointcut = this.declaredPointcut;
      this.lazy = false;
      //创建advice对象 点击进入--》
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }
}

测试参数

 来到:

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
   //创建Advice对象,如上: 
   Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
         this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
   return (advice != null ? advice : EMPTY_ADVICE);
}

 9、ctrl+t  getAdvice 进入 ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable

@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

   //获取有@Aspect注解的类
   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);

   //找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }

   // If we get here, we know we have an AspectJ method.
   // Check that it's an AspectJ-annotated class
   if (!isAspect(candidateAspectClass)) {
      throw new AopConfigException("Advice must be declared inside an aspect type: " +
            "Offending method '" + candidateAdviceMethod + "' in class [" +
            candidateAspectClass.getName() + "]");
   }

   if (logger.isDebugEnabled()) {
      logger.debug("Found AspectJ method: " + candidateAdviceMethod);
   }

   AbstractAspectJAdvice springAdvice;

   //根据不同的注解类型创建不同的advice类实例
   switch (aspectJAnnotation.getAnnotationType()) {
      case AtPointcut:
         if (logger.isDebugEnabled()) {
            logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
         }
         return null;
      case AtAround:
         //实现了MethodInterceptor接口
         springAdvice = new AspectJAroundAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtBefore:
         //实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
         springAdvice = new AspectJMethodBeforeAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfter:
         //实现了MethodInterceptor接口
         springAdvice = new AspectJAfterAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfterReturning:
         //实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
         springAdvice = new AspectJAfterReturningAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterReturningAnnotation.returning())) {
            springAdvice.setReturningName(afterReturningAnnotation.returning());
         }
         break;
      case AtAfterThrowing:
         //实现了MethodInterceptor接口
         springAdvice = new AspectJAfterThrowingAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
            springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
         }
         break;
      default:
         throw new UnsupportedOperationException(
               "Unsupported advice type on method: " + candidateAdviceMethod);
   }

   // Now to configure the advice...
   springAdvice.setAspectName(aspectName);
   springAdvice.setDeclarationOrder(declarationOrder);
   String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
   if (argNames != null) {
      springAdvice.setArgumentNamesFromStringArray(argNames);
   }

   //计算argNames和类型的对应关系
   springAdvice.calculateArgumentBindings();

   return springAdvice;
}

测试参数

继续

 然后返回

10、返回的 Advice 集合,返回途中经过几次过滤,重要的一次如下:

点击  findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			//看看当前类是否在这些切面的pointCut中.掉类和方法的match过程
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}

点击  AopUtils.findAdvisorsThatCanApply 接口

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		for (Advisor candidate : candidateAdvisors) {
			//如果是引介切面并且匹配
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		//调用pointCut中的ClassFilter 和methodMatcher的match方法的过程
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			if (canApply(candidate, clazz, hasIntroductions)) {//点击进入
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}

 点击 canApply(candidate, clazz, hasIntroductions)ff

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);//点击进入
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

点击canApply(pca.getPointcut(), targetClass, hasIntroductions)方法

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		//调用ClassFilter的matches方法,判断类是否匹配
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		//判断类中方法是否匹配,,有些可能是方法上面有注解的拦截,所以需要判断方法是否匹配
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if (introductionAwareMethodMatcher != null ?
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

测试参数演示不配当前实例:

 换一个不匹配的实例

主要判断当前的bean是否在这个目录下,还有一种情况后期会分享就是,判断该方法是否有对应的自定义注解。 

匹配的实例:

 

工程中共有10个切面对象,其中有9个可以匹配到当前对象。 

返回之前添加一个默认切面  extendAdvisors(eligibleAdvisors); 进入AspectJAwareAdvisorAutoProxyCreator

	@Override
	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
		AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
	}

点击

public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
		// Don't add advisors to an empty list; may indicate that proxying is just not required
		if (!advisors.isEmpty()) {
			boolean foundAspectJAdvice = false;
			for (Advisor advisor : advisors) {
				// Be careful not to get the Advice without a guard, as this might eagerly
				// instantiate a non-singleton AspectJ aspect...
				if (isAspectJAdvice(advisor)) {
					foundAspectJAdvice = true;
					break;
				}
			}
			if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
				advisors.add(0, ExposeInvocationInterceptor.ADVISOR);//添加默认的切面
				return true;
			}
		}
		return false;
	}

点击看看,此切面作用是处理传参的,只要有@Aspect注解的类,就会多一个这样的切面, 因为切面调用时是链路调用。

public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
		@Override
		public String toString() {
			return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
		}
	};

  过滤后返回通用接口 Advice,直到这里转换成数组,承接下面的接口

    11、到这里AOP 的切面已经生成,可以去创建代理了,入口如下:

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果有切面,则生成该bean的代理
if (specificInterceptors != DO_NOT_PROXY) {
   this.advisedBeans.put(cacheKey, Boolean.TRUE);
   //把被代理对象bean实例封装到SingletonTargetSource对象中,代理类的调用入口--》下篇介绍
   Object proxy = createProxy(
         bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
   this.proxyTypes.put(cacheKey, proxy.getClass());
   return proxy;
}

到此收获切面注解封装成对象advisors,准备结合当前的实例生成代理类,代理类的调用流程下一篇解析,敬请期待!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值