Spring AOP原理源码级解析

2021/11/16 14:10:05

本文主要是介绍Spring AOP原理源码级解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.AOP核心接口

AnnotationAwareAspectJAutoProxyCreator

1.1查找核心接口

1.Spring通过注解**@EnableAspectJAutoProxy**开启aop切面功能:

其中有**@Import(AspectJAutoProxyRegistrar.class)**,把AspectJAutoProxyRegistrar实例加入IOC容器中;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {...}

2.AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,重写registerBeanDefinitions,在IOC容器解析配置类时(refresh-invokeBeanFactoryPostProcessors)会进行调用。

因此可以往容器中注入一个BeanDefinition;

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
  @Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  ...
}

3.从AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法依次进入,最终会在容器中注册一个AnnotationAwareAspectJAutoProxyCreator的bean定义,之后IOC容器会注册bean的后置处理器(refresh-registerBeanPostProcessors)。

通过AnnotationAwareAspectJAutoProxyCreator的后置处理器实现AOP的功能。

	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
	}


	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
		//注册AnnotationAwareAspectJAutoProxyCreator
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

1.2核心接口继承关系

diagram

2.流程接口

解析切面:从IOC容器中获取处的所有bean的名称,从中找到所有标记了@Aspect的切面类,将所有的通知advise解析成advisor(包含advise和pointcut),并加入到缓存中;

创建代理:拿到之前解析到的所有advisors,根据其中pointcut对应去匹配matches(分为两次筛选:类级别和方法级别),匹配到的bean会根据不同情况创建动态代理createProxy;

调用代理:调用增强方法就会来到JdkDynamicAopProxy#invoke,是否暴露代理对象到线程变量ThreadLocal currentProxy中,把aop的advisor全部转化为拦截器,通过责任链模式依此调用拦截器链的invoke方法。

2.1解析切面Aspect

1postProcessBeforeInstantiation

AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor,在bean实例化前阶段(resolveBeforeInstantiation)执行父类 AbstractAutoProxyCreator的postProcessBeforeInstantiation

	//AbstractAutoProxyCreator#postProcessBeforeInstantiation

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		...
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}
...
	}

	protected boolean isInfrastructureClass(Class<?> beanClass) {
		/**
		 * 假如当前正在创建的Bean的class是Advice PointCut Advisor  AopInfrastructureBean
		 * 直接跳过不需要解析
		 */
		boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
				Pointcut.class.isAssignableFrom(beanClass) ||
				Advisor.class.isAssignableFrom(beanClass) ||
				AopInfrastructureBean.class.isAssignableFrom(beanClass);
		...
		return retVal;
	}


	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		return false;
	}

2shouldSkip

跟到AspectJAwareAdvisorAutoProxyCreator#shouldSkip方法实现

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // 找到候选的Advisors
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   ...
   return super.shouldSkip(beanClass, beanName);
}

3findCandidateAdvisors

AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

protected List<Advisor> findCandidateAdvisors() {
   Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
   return this.advisorRetrievalHelper.findAdvisorBeans();
}

AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors方法实现

@Override
protected List<Advisor> findCandidateAdvisors() {
   // 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.
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

*4buildAspectJAdvisors

用来解析切面类,去容器中获取到所有的切面信息保存到缓存中:this.advisorsCache.put(beanName, classAdvisors);

public List<Advisor> buildAspectJAdvisors() {
   ...
     				//去容器中获取到所有的组件的名称
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            //遍历我们从IOC容器中获取处的所有bean的名称
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               //通过beanName去容器中获取到对应class对象
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               //根据class对象判断是不是切面,判断当前类有没有@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                  //是切面类加入到缓存中
                  aspectNames.add(beanName);
                  //把beanName和class对象构建成为一个AspectMetadata
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

                     //构建切面注解的实例工厂
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     //真正去获取通知对象,切面中一个通知advise就会解析成一个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 {
                    ...
}

*5getAdvisors

	@Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		...
		//获取到切面类中除了标注了@PointCut注解的所有方法并排序(Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class,为了责任链调用)
		for (Method method : getAdvisorMethods(aspectClass)) {
			//遍历解析切面中的方法,将切点表达式和通知封装到InstantiationModelAwarePointcutAdvisorImpl对象中
			Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}
    ...

2.2创建代理

1postProcessAfterInitialization

AnnotationAwareAspectJAutoProxyCreator 实现了 BeanPostProcessor,bean初始化后阶段(applyBeanPostProcessorsAfterInitialization)执行父类 AbstractAutoProxyCreator的postProcessAfterInitialization

//AbstractAutoProxyCreator#postProcessAfterInitialization

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         //返回动态代理实例
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

2wrapIfNecessary

//AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   ...

   //1.根据当前bean找到匹配的Advisor,直接去缓存中获取Advisors
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //2.创建代理
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      //3.放到缓存中
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

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

2.1getAdvicesAndAdvisorsForBean

//AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

@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();
}
2.1.1findEligibleAdvisors
	//AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 1.从缓存中拿Advisors
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 2.判断切点是否命中当前Bean
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		// 3.对advisor进行排序,索引大的在前面
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
2.1.1.1findCandidateAdvisors

findEligibleAdvisors—>findCandidateAdvisors—>buildAspectJAdvisors,调用链同上,但这次不需要去解析而是直接去缓存中获取:this.advisorsCache.get(aspectName);

//BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

public List<Advisor> buildAspectJAdvisors() {
	...
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      ...
}
*2.1.1.2canApply

findEligibleAdvisors—>findAdvisorsThatCanApply—>findAdvisorsThatCanApply—>canApply,从candidateAdvisors中找到适合当前正在创建类的Advisors

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   ...
      //转为PointcutAdvisor类型
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      //找到真正能用的增强器
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		...
}


	public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		// 进行类级别过滤(通过AspectJ)
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}
		/**
		 * 进行方法级别过滤
		 */
		//如果pc.getMethodMatcher()返回TrueMethodMatcher则匹配所有方法
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		//判断匹配器是不是IntroductionAwareMethodMatcher  只有AspectJExpressionPointCut才会实现这个接口
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		//创建一个集合用于保存targetClass 的class对象
		Set<Class<?>> classes = new LinkedHashSet<>();
		//判断当前class是不是代理的class对象
		if (!Proxy.isProxyClass(targetClass)) {
			//加入到集合中去
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		//获取到targetClass所实现的接口的class对象,然后加入到集合中
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		//循环所有的class对象
		for (Class<?> clazz : classes) {
			//通过class获取到所有的方法
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			//循环我们的方法
			for (Method method : methods) {
				//通过methodMatcher.matches来匹配我们的方法
				if (introductionAwareMethodMatcher != null ?
						// 通过切点表达式进行匹配 AspectJ方式
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						// 通过方法匹配器进行匹配 内置aop接口方式
						methodMatcher.matches(method, targetClass)) {
					// 只要有1个方法匹配上了就创建代理
					return true;
				}
			}
		}

		return false;
	}

2.2createProxy

//AbstractAutoProxyCreator#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);
	 //如果设置了 <aop:aspectj-autoproxy proxy-target-class="true"/>强制使用cglib
   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
	 //真正的创建代理对象
   return proxyFactory.getProxy(getProxyClassLoader());
}
*2.2.1createAopProxy

getProxy最终会调用到DefaultAopProxyFactory#createAopProxy

	//DefaultAopProxyFactory#createAopProxy创建代理对象:
	//设置了ProxyTargetClass或者没有接口,并且不是接口或者动态代理类,就会用cglib;
	//设置了ProxyTargetClass或者没有接口,但是本身是接口或者动态代理类,就会用jdk;
	//没有设置ProxyTargetClass或者有接口,就会用jdk。
	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		//判断是否设置了ProxyTargetClass或者是否有接口
		if (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.");
			}
			//是接口或者动态代理类
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			//cglib代理
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			//jdk动态代理
			return new JdkDynamicAopProxy(config);
		}
	}

2.3代理类的调用

1.invoke

以JdkDynamicAopProxy为例,调用增强方法就会来到JdkDynamicAopProxy#invoke

@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
      ...

      Object retVal;

      /**
       * 这个配置是【是否暴露代理对象到线程变量ThreadLocal<Object> currentProxy中】,需要设置exposeProxy = true使用。
       *如果暴露,在jdk代理中,在本类方法A中调用本类方法B,不会再次执行动态代理方法。
       */
      if (this.advised.exposeProxy) {
         //把代理对象暴露到线程变量中
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }

      //获取目标对象
      target = targetSource.getTarget();
      //获取目标对象的class
      Class<?> targetClass = (target != null ? target.getClass() : null);

      //把aop的advisor全部转化为拦截器,通过责任链模式依此调用拦截器的invoke方法
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      //判断拦截器链是否为空
      if (chain.isEmpty()) {
         //通过反射直接调用执行
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         //调用执行
         retVal = invocation.proceed();
      }

      ...

2.proceed

ReflectiveMethodInvocation#proceed,递归调用proceed,直到执行到最后一个拦截器执行invokeJoinpoint,就是调用被增强的方法

@Override
@Nullable
public Object proceed() throws Throwable {
   //从-1开始,结束条件执行目标方法是下标=拦截器的长度-1(执行到了最后一个拦截器)
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }

   /**
    * 获取第一个方法拦截器使用的是前++
    */
   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;
      if (dm.methodMatcher.matches(this.method, this.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方法,传入的是this,当前的方法拦截器对象
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

2.0ExposeInvocationInterceptor#invoke

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   MethodInvocation oldInvocation = invocation.get();
   //记录当前正在执行的拦截器
   invocation.set(mi);
   try {
     	//递归调用
      return mi.proceed();
   }
   finally {
      invocation.set(oldInvocation);
   }
}

2.1AspectJAfterThrowingAdvice#invoke

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      //执行下一个拦截器
      return mi.proceed();
   }
   catch (Throwable ex) {
      //抛出异常
      if (shouldInvokeOnThrowing(ex)) {
         //执行异常通知
         invokeAdviceMethod(getJoinPointMatch(), null, ex);
      }
      throw ex;
   }
}

2.2AfterReturningAdviceInterceptor#invoke

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   //本拦截器返回通知拦截器,所抛出异常就不会执行返回通知的方法,执行下一个拦截器(后置拦截器对象)
   Object retVal = mi.proceed();
   //返回通知方法
   this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
   return retVal;
}

2.3AspectJAfterAdvice#invoke

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      //本拦截器是后置通知拦截器对象,执行下一个通知
      return mi.proceed();
   }
   finally {
      //后置通知的方法总是会被执行 因为是finally包裹的
      invokeAdviceMethod(getJoinPointMatch(), null, null);
   }
}

2.4MethodBeforeAdviceInterceptor#invoke

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
   //本拦截器是前置通知拦截器对象,先执行前置通知的方法
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
   //执行下一个拦截器,但是该拦截器是最后一个了,那么就会调用目标方法
   return mi.proceed();
}

3.jdk和cglib区别

jdk动态代理代理的是***接口***,jdk底层会自己根据接口新生成***一个***动态代理的$Proxy.class字节码文件,该.class文件会***实现***需要代理的接口并重写具体方法,这也是为什么jdk动态代理一定要有接口;通过***反射***的方式调用具体方法;在jdk代理中,在本类方法A中调用本类方法B,***不会再次***执行动态代理方法。

执行Proxy.newProxyInstance—>JDK生成$Proxy.class字节码文件—>执行方法A—>会去调用InvocationHandler.invoke方法—>通过反射调用具体方法。

cglib代理的是***具体实现类***,底层利用ASM组件根据具体类生成***多个***cglib.class字节码文件,该.class文件会***继承***需要代理的具体类并重写具体方法,所以cglib代理不需要指定接口;***直接调用***实现了被代理类的动态代理类(子类)方法;在cglib代理中,在本类方法A中调用本类方法B,***会重复***执行动态代理方法。

执行enhancer.create—>ASM生成多个cglib.class字节码文件—>执行方法A—>会去调用MethodInterceptor.intercept方法—>直接调用子类具体方法。



这篇关于Spring AOP原理源码级解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程