13-springAop 源码深入

Aop 源码深入

一、核心步骤

1.1 注册核心处理类

1.1.1 导入AspectJAutoProxyRegistrar
  • 第一步是注册关键的注册类:通过@EnableAspectJAutoProxy导入了一个Registrar(AspectJAutoProxyRegistrar,实现ImportBeanDefinitionRegistrar)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	//默认使用jdk代理
	boolean proxyTargetClass() default false;
    
	boolean exposeProxy() default false;
}
1.1.2 注册AnnotationAwareAspectJAutoProxyCreator
  • AspectJAutoProxyRegistrar会往IOC容器注册一个Bean,BeanId是"org.springframework.aop.config.internalAutoProxyCreator",类型是AnnotationAwareAspectJAutoProxyCreator,核心代码如下:
//AopConfigUtils
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

1.2 解析增强器

  • 下面是Bean的生命周期图,这一步我们来跟着代码调试,结合源码和Bean生命周期来看看整个过程,具体的代码附在文章最后;

在这里插入图片描述

  • 增强器的解析是在AOP核心类InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法时解析的,也就是实例化之前,对应图中第三列的第一个框。
  • 在创建Bean的时候会调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,而AOP的核心类类型是AnnotationAwareAspectJAutoProxyCreator就是这个类的子类,因此它的这个方法会被调用。这个方法是在父类AbstractAutoProxyCreator中实现好的,在这里shouldSkip里面会去解析全部的增强器。这个过程的细节在BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors方法里面。
1.2.1 第一步:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
  • 这一步在AbstractAutowireCapableBeanFactory#createBean()内部调用resolveBeforeInstantiation的时候,触发实例化之前调用,这一步会调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法,方法如下:
@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			//这里的shouldSkip是很关键的,它会调用子类AnnotationAwareAspectJAutoProxyCreator的shouldSkip,方法
			//里面会解析全部的增强器
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}
        //后面这一段通常不会执行,很少从这次返回,通常前面就返回了
		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
1.2.2 第二步:解析增强器
  • 这一步流程比较多,大致是:shouldSkip() -> findCandidateAdvisors() -> BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors ->
  • AbstractAutowireCapableBeanFactory#shouldSkip():内部解析增强器
    //这里的逻辑是,增强器是AspectJPointcutAdvisor类型并且beanName和增强器名称一样的时候,这时候就会跳过,返回true,跳过的话回将对应的Bean标记为false,一般的Bean都不会标记为false的
    @Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}
  • AbstractAutowireCapableBeanFactory#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) {
		    //这里面buildAspectJAdvisors是获取增强器的关键
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
	
  • BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors(): 构建增强器
//缓存已经解析过的切面类名称
@Nullable
private volatile List<String> aspectBeanNames;
	
public List<Advisor> buildAspectJAdvisors() {
        //1.切面类只会解析一次,解析后会缓存起来
		List<String> aspectNames = this.aspectBeanNames;
        //2.List aspectNames保存了全部切面类的名称,首次是空的,会将切面类的名称加进去,后面再进来就会走后面的获取逻辑,不需要再次解析了
		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new LinkedList<>();
					aspectNames = new LinkedList<>();
					//得到全部的Bean,并进行遍历处理,这里的类型是Object因此会获取全部的Bean
					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);
						//null类型不处理
						if (beanType == null) {
							continue;
						}
						//是Aspect类型的Bean才处理,这里面的判断其实就是一句话:return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));包含Aspect切面注解,并且字段名称不能以ajc$开头
						//如果不满足,则不会处理,外面的循环一直等到LogAspect出现,才开始进去下面的逻辑进行处理
						if (this.advisorFactory.isAspect(beanType)) {
							//把Aspect切面类的名字加到集合
							aspectNames.add(beanName);
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
								MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								//获取切面类的增强方法
								List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
								//Bean是单例的,就加入到缓存
								if (this.beanFactory.isSingleton(beanName)) {
									this.advisorsCache.put(beanName, classAdvisors);
								}
								else {//反之就把factory加到缓存
									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();
		}
		//如果不是空的,就把全部的切面类对应的增强器Advisor全部遍历出来,打包返回
		List<Advisor> advisors = new LinkedList<>();
		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;
	}
  • ReflectiveAspectJAdvisorFactory#getAdvisors(): 将方法转换为Advisor增强对象
	//getAdvisors辅助类,获取增强器,里面会遍历切面类的全部方法,转换为增强器
    @Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	    //获取切面类名称
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		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);

        //获取切面类的全部方法,将方法转换为增强对象Advisor
		List<Advisor> advisors = new LinkedList<>();
		//这里的getAdvisorMethods会返回切面类的全部方法,但是会排除掉一种方法不返回,就是标记了@Pointcut的方法不返回,
		//这里容易理解,因为我们是要获取增强的方法,也就是目标方法前后的那些方法,但是@Pointcut
		//是用来定义对哪些方法进行拦截的,因此这里是不需要的,不过对于那些其他的方法,比如继承自Object的方法,
		//这里也一并返回了,不过这些方法在获取Advisor对象的时候会是null,因此并没有影响 
		for (Method method : getAdvisorMethods(aspectClass)) {
		    //这个getAdvisor里面会根据切面类里面的方法,获取方法的表达式,最后返回一个增强对象Advisor,Advisor里面封装了切面方法,切面类等很多信息
		    //对于非增强的方法,因此注解上的切面表达式是null,因此在getAdvisor里面会返回null
		    //最后advisors里面就是增强方法对于的封装后的增强对象,在LogAspect里面有5个增强方法,对于的advisors集合里面也有五个元素
			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()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}
		return advisors;
	}

1.3 创建代理对象

  • 经过前面的注册核心处理类和解析增强器,后面就需要织入了。简而言之就是为需要增强的对象返回一个增强后的代理对象,代理对象是包含对应的增强方法的对象,我们看看这个过程是如何完成的。
1.3.1 目标类处理
  • 我们先看看处理目标类的逻辑,按照前面的Bean的生命周期,MyTarget类会在初始化的最后一步也就是BeanPostProcessor处理后完成初始化,而代理对象就是在这一步返回的。我们直接断点到AbstractAutowireCapableBeanFactory#line1702的#invokeInitMethods()方法,直到MyTartget创建再跟进:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		//省略...
		//初始化方法调用
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		//省略...
		//BeanPostProcessor后置处理
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
1.3.2 返回代理对象
  • 后置处理器返回代理对象: 后置处理器调用入口
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {
	Object result = existingBean;
    //循环调用后置处理器处理,这里会返回代理对象
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}
  • AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization: 后置处理器方法返回代理对象
 	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
  • AbstractAutoProxyCreator#wrapIfNecessary: 生成代理对象
//AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//省略... 
		//获取增强器
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//创建代理对象
			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;
	}
  • AbstractAutoProxyCreator#createProxy: 通过代理工厂获取代理对象
//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);

		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());
	}
	
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
    }
1.3.3 获取AopProxy
  • 前面的代理工厂实际上还不能直接返回代理对象,需要先createAopProxy获得一个AopProxy,然后使用AopProxy.getProxy获取增强后的代理对象,AopProxy包含几个实现类:JdkDynamicAopProxy和CglibAopProxy、ObjenesisCglibAopProxy(CglibAopProxy的子类),对应不同的代理方式。
  • 这里简单说一下,获取代理对象的两种方式,
1.JDK的方式是通过Proxy类来实现的,代理对象是Proxy的子类,目标类需要实现接口才行
2.Cglib是通过字节码技术,代理类是目标类的子类
  • 为目标对象创建代理对象的时候,会使用JDK代理或CGlib代理,究竟是用哪一种?通过源码判断如下:
public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

//DefaultAopProxyFactory#createAopProxy
@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		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.");
			}
			//1.如果目标对象是一个接口,或者是一个已经被代理过的对象,那么就使用JDK代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			//2.不满足JDK代理的条件就使用Cglib动态代理,ObjenesisCglibAopProxy()是CglibAopProxy子类,是一个AopProxy实例
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

//判断cl是不是代理类,通过集合proxyClassCache中是否有缓存来判断
public static boolean isProxyClass(Class<?> cl) {
        return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
1.3.4 AopProxy获取代理对象
  • AopProxy#getProxy():用于获取代理对象
//AopProxy创建代理对象的过程:
//ProxyFactory#getProxy(java.lang.ClassLoader)

public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
}

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
		try {
		//获取目标类
		Class<?> rootClass = this.advised.getTargetClass();

		///省略... 
		// Configure CGLIB Enhancer...
		//配置Cglib增强对象,通过Enhancer实现,设置父类和相关的CallBacks
		Enhancer enhancer = createEnhancer();
		if (classLoader != null) {
			enhancer.setClassLoader(classLoader);
			if (classLoader instanceof SmartClassLoader &&
				((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
				enhancer.setUseCache(false);
			}
		}
		enhancer.setSuperclass(proxySuperClass);
		enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

		Callback[] callbacks = getCallbacks(rootClass);
		Class<?>[] types = new Class<?>[callbacks.length];
		for (int x = 0; x < types.length; x++) {
		types[x] = callbacks[x].getClass();
		}
		// fixedInterceptorMap only populated at this point, after getCallbacks call above
		enhancer.setCallbackFilter(new ProxyCallbackFilter(
				this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
		enhancer.setCallbackTypes(types);

		// Generate the proxy class and create a proxy instance.
		//创建增强后的代理对象
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	//省略...
}

1.4 代理对象执行分析

  • 断点进去,首先到了CglibAopProxy.DynamicAdvisedInterceptor#intercept方法
@Override
		@Nullable
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Object target = null;
			//1.获取目标方法拦截器链
			//返回空
			TargetSource targetSource = this.advised.getTargetSource();
			try {
			    //跳过
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
				target = targetSource.getTarget();
				Class<?> targetClass = (target != null ? target.getClass() : null);
				//根据类型获取拦截器链
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				// Check whether we only have one InvokerInterceptor: that is,
				// no real advice, but just reflective invocation of the target.
				//拦截器为空,那就直接调用方法即可,
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					// We can skip creating a MethodInvocation: just invoke the target directly.
					// Note that the final invoker must be an InvokerInterceptor, so we know
					// it does nothing but a reflective operation on the target, and no hot
					// swapping or fancy proxying.
					Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
					retVal = methodProxy.invoke(target, argsToUse);
				}
				else {
				    //拦截链不为空,使用CglibMethodInvocation对象的proceed调用目标方法
				    //这里将目标对象,目标方法,拦截器链等信息都传入给了CglibMethodInvocation对象,proceed是重点
					// We need to create a method invocation...
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				//处理结果
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null && !targetSource.isStatic()) {
					targetSource.releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}
  • ReflectiveMethodInvocation#proceed():方法,
@Override
	@Nullable
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		//currentInterceptorIndex默认-1,记录当前拦截器索引,右边的值是5,也就是增强器的个数
		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 {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
  • 将所有的增强器转换为方法拦截器MethodInterceptor,通过MethodInterceptor方法拦截器机制来执行。

二、AOP拦截器和调用链分析

  • AOP返回代理的过程,会将切面里面写的增强方法转换为增强对象,在方法调用时,会将Advisor增强对象转换为方法拦截器,通过拦截器链来完成依次调用。
  • 增强对象调用的时候,本质是内部的拦截器对象之间的调用,因此我们分析几种拦截器,分析几种增强的行为。在调用的时候主要是invoke方法,因此我们就关注该方法。

2.1 拦截器

2.1.1 ExposeInvocationInterceptor
  • ExposeInvocationInterceptor的invoke会继续调用MethodInvocation的proceed();
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
		    //继续调用MethodInvocation的proceed();
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}
2.1.2 AspectJAfterThrowingAdvice
  • AspectJAfterThrowingAdvice是异常拦截器,如果有的话,它是在拦截器链的第2个,注意第二个是下标为1。
  • 在AspectJAfterThrowingAdvice的invoke中,租后会回调MethodInvocation的proceed方法;
public Object invoke(MethodInvocation mi) throws Throwable {
	try {
		return mi.proceed();
	}
	catch (Throwable ex) {
		if (shouldInvokeOnThrowing(ex)) {
			invokeAdviceMethod(getJoinPointMatch(), null, ex);
		}
		throw ex;
	}
}
2.1.3 AfterReturningAdviceInterceptor和AspectJAfterReturningAdvice
  • 在AfterReturningAdviceInterceptor的invoke的方法中,我们看到他也会回调MethodInvocation的proceed方法,调用成功之后会调用afterReturning,我们往后面看就明白了,afterReturning是AspectJAfterReturningAdvice的方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
	Object retVal = mi.proceed();
	//@AfterReturning方法调用
	this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
	return retVal;
}
  • AspectJAfterReturningAdvice
@Override
	public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
		if (shouldInvokeOnReturnValueOf(method, returnValue)) {
			invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
		}
	}
2.1.4 AspectJAfterAdvice
@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
		    //@After方法调用
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
2.1.5 AspectJAroundAdvice
@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		if (!(mi instanceof ProxyMethodInvocation)) {
			throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
		return invokeAdviceMethod(pjp, jpm, null, null);
	}
2.1.6 MethodBeforeAdviceInterceptor
@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
	    //调用@Before方法
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		//
		return mi.proceed();
	}

2.2 调用分析

  • 按照之前的代码,我们假设现在增强对象MyTarget具备5个增强对象,分别是:@Before、@After、@AfterReturning、@AfterThrowing、@Around ,那么其执行顺序应该如下
正常:@Around开始 ->@Before-> 目标方法 -> @Around完毕 -> @After ->@AfterReturning 
异常:@Around开始 ->@Before-> 目标方法 ->  @After ->@AfterThrowing 
  • 我们先看看正常情况是怎么调用的,调用过程我们已经在1.4分析了,是通过ReflectiveMethodInvocation#proceed来调用的,我们通过代码解读一下
@Override
	@Nullable
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		//currentInterceptorIndex首次是-1,this.interceptorsAndDynamicMethodMatchers.size() - 1是5,只有最后一次才会进去这个逻辑
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
        //一次获取方法拦截器,拦截器的顺序是前面的2.1.1 - 2.1.6那六个,顺序都是一致的
		Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		//这里调试都会走到else的逻辑
		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方法
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

2.3 递归调用

  • 现在我们看看这个过程,拦截器下标0-5分别对应2.1.1 - 2.1.6六个拦截器,类型粗略看就是:
ExposeInvocationInterceptor->AfterThrowing->AfterReturning->After->Around->Before
  • 首先调用的是ExposeInvocationInterceptor的invoke,里面回调proceed,然后递归调用第二个拦截器AfterThrowing的invoke,再次回调proceed,调用
  • AfterReturningAdviceInterceptor的invoke,还是回调proceed,里面再回调AspectJAfterAdvice的invoke,再调用AspectJAroundAdvice,AspectJAroundAdvice
    里面调用目标方法,然后继续回到proceed,调用Before方法,简图如下:

在这里插入图片描述

  • 上面调用栈大致反应出调用的情况,可能细节未必表示的清楚,

2.4 JDK代理

  • 另外如果目标类实现了接口,那么就会使用JDK代理,使用JDK代理的时候,如果调用的是需要增强的方法,那么也是按照这样的调用链来组织的,代码如下:
//JdkDynamicAopProxy#invoke

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
		    //Object的方法,或者其他的方法处理,代码省略...
			Object retVal;

			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// Get the interception chain for this method.
			//获取方法拦截链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
			    //没有增强,代码省略...
			}
			else {
			    //增强,我们看到这里的逻辑和Cglib的实现是一模一样的
				// We need to create a method invocation...
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
				retVal = proxy;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
         //省略...
	}

三、小结

  • Aop总体原理第一步是:通过注册器AspectJAutoProxyRegistrar注册核心处理器AnnotationAwareAspectJAutoProxyCreator,
  • 第二步:解析增强器,通过核心处理器的实例化前置接口,来将切面类的增强方法转换为Advisor对象
  • 第三步:创建代理对象;会在对象的初始化后置接口寻找合适的增强器,创建一个增强后的代理对象,这个对象内部包含其能够使用的增强器。
  • 第四步:方法调用;调用方法的时候,代理对象会先获取到该方法对应的拦截器链(不同方法拦截器链可能不一样),按照类似于递归压栈的方式调用增强方法和目标方法
这里增强的代理对象中包含一个AdvisedSupport的辅助类,AdvisedSupport里面包含所有的增强器Advisor[],因此代理对象可以根据调用的方法来组织调用链
  • 这里面的方法绕来绕去还是有点复杂的,写的也不是特别清晰,需要多看看源码…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值