Spring AOP源码3:实现代理

参考文章:

《Spring AOP源码学习:创建 AOP 代理》

《Spring AOP源码学习:一次请求调用全流程》

前文:

《Spring AOP源码:开启注解读取》

《Spring AOP源码2:查找增强器》

        写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。

目录

一、createProxy

        1、createProxy

        2、getProxy

        3、createAopProxy

二、JdkDynamicAopProxy

        1、JdkDynamicAopProxy

        2、getProxy

        3、invoke 

        4、ReflectiveMethodInvocation#proceed

二、invoke

        1、AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice

        2、DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice

        3、GlobalAdvisorAdapterRegistry

        4、DefaultAdvisorAdapterRegistry

        4.1、DefaultAdvisorAdapterRegistry

        4.2、getInterceptors

        5、invoke

        6、invokeJoinpoint


        在前文中,我们找到了所有适用于当前bean的增强器,本文我们就为他们创建适用于他们的代理类。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 1.判断当前bean是否在targetSourcedBeans缓存中存在(已经处理过),如果存在,则直接返回当前bean
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 2.在advisedBeans缓存中存在,并且value为false,则代表无需处理
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
 
    // Create proxy if we have advice.
    // 4.获取当前bean的Advices和Advisors
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 5.如果存在增强器则创建代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 5.1 创建代理对象:这边SingletonTargetSource的target属性存放的就是我们原来的bean实例(也就是被代理对象),
        // 用于最后增加逻辑执行完毕后,通过反射执行我们真正的方法时使用(method.invoke(bean, args))
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        // 5.2 创建完代理后,将cacheKey -> 代理类的class放到缓存
        this.proxyTypes.put(cacheKey, proxy.getClass());
        // 返回代理对象
        return proxy;
    }
    // 6.标记为无需处理
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

一、createProxy

        1、createProxy

        在生成代理类之前,主要做了两件事,判断使用 Jdk 代理还是 Cglib 代理以及设置相关的属性。

protected Object createProxy(
        Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
     // 如果当前beanFactory实现了ConfigurableListableBeanFactory接口,则将需要被代理的对象暴露出来
    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }
 
    // 创建代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    // 从当前对象复制属性值
    proxyFactory.copyFrom(this);
 
    // 检查proxyTargetClass属性,判断对于给定的bean使用类代理还是接口代理,
    // proxyTargetClass值默认为false,可以通过proxy-target-class属性设置为true
    if (!proxyFactory.isProxyTargetClass()) {
        // 检查preserveTargetClass属性,判断beanClass是应该基于类代理还是基于接口代理
        if (shouldProxyTargetClass(beanClass, beanName)) {
            // 如果是基于类代理,则将proxyTargetClass赋值为true
            proxyFactory.setProxyTargetClass(true);
        } else {
            // 判断目标类是否实现了相关接口
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }
    // 将拦截器封装为Advisor(advice持有者)
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 将advisors添加到proxyFactory
    proxyFactory.addAdvisors(advisors);
    // 设置要代理的类,将targetSource赋值给proxyFactory的targetSource属性,之后可以通过该属性拿到被代理的bean的实例
    proxyFactory.setTargetSource(targetSource);
    // 自定义ProxyFactory,空方法,留给子类实现
    customizeProxyFactory(proxyFactory);
 
    // 用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置)
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }
 
    // 使用proxyFactory生成代理
    return proxyFactory.getProxy(getProxyClassLoader());
}

        2、getProxy

        可以理解为一个工厂方法,返回值是一个 AopProxy 类型的对象,其内部根据具体的条件生成相应的子类对象,即 JdkDynamicAopProxy 和 ObjenesisCglibAopProxy。后面则通过调用 AopProxy.getProxy() 方法获取代理过的对象。

public Object getProxy(ClassLoader classLoader) {
    // 首先创建AopProxy对象,其主要有两个实现:JdkDynamicAopProxy和ObjenesisCglibAopProxy,
    // 分别用于Jdk和Cglib代理类的生成,其getProxy()方法则用于获取具体的代理对象
    return createAopProxy().getProxy(classLoader);
}

        3、createAopProxy

        真正创建了AopProxy的实现类,根据不同的条件判断是创建JdkDynamicAopProxy 还是 ObjenesisCglibAopProxy,这两个分别对应了JDK与CGLIB的代理类生成方式。

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        // 1.激活此代理配置
        activate();
    }
    // 2.创建AopProxy
    return getAopProxyFactory().createAopProxy(this);
}
 
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1.判断使用JDK动态代理还是Cglib代理
    // optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
    // 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效
    // proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class="true" />
    // hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        // 拿到要被代理的对象的类型
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            // TargetSource无法确定目标类:代理创建需要接口或目标。
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        // 如果被代理的类是一个接口,或者被代理的类是使用Jdk代理生成的类,此时还是使用Jdk代理
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            // JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象
            return new JdkDynamicAopProxy(config);
        }
        // Cglib代理
        return new ObjenesisCglibAopProxy(config);
    } else {
        // JDK动态代理
        return new JdkDynamicAopProxy(config);
    }
}

  

二、JdkDynamicAopProxy

        1、JdkDynamicAopProxy

        JdkDynamicAopProxy的构造方法,内容很简单,就是将之前创建的ProxyFactory对象赋值给成员变量advised。

// JdkDynamicAopProxy.java
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
    Assert.notNull(config, "AdvisedSupport must not be null");
    if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
        throw new AopConfigException("No advisors and no TargetSource specified");
    }
    // config赋值给advised
    this.advised = config;
}
 

        2、getProxy

        (1)获取生成代理对象所需要实现的所有接口

        (2)然后判断接口中是否包含有 equals () 和 hashCode () 方法,因为这将用于判断生成的代理类是使用用于定义的 equals () 和 hashCode () 方法还是使用自动生成的方法

        (3)通过动态代理生成代理对象

        这里需要注意的是 JdkDynamicAopProxy 不仅实现了 AopProxy 接口还实现了 InvocationHandler 接口,因而这里生成代理对象的时候传入的 InvocationHandler 对象是 this。

@Override
public Object getProxy(ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }
    // 拿到要被代理对象的所有接口
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    // 找到接口中是否包含有equals()和hashCode()方法,并进行标识
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    // 通过classLoader、接口、InvocationHandler实现类生成代理对象
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

        到这里,使用JDK动态代理创建的代理类已经完成了,当JDK动态代理的类被调用时,会走到 JdkDynamicAopProxy#invoke 方法。

        3、invoke 

        判断目标方法是否为 Spring 织入的 Advised 中的方法,如果是,则调用当前 advised 对象中相应的方法。然后就会获取当前方法需要织入的代理逻辑的调用链。接着就会将目标对象和调用链逻辑封装为 ReflectiveMethodInvocation,并进行调用。

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    MethodInvocation invocation;
    Object oldProxy = null;
    boolean setProxyContext = false;
 
    // advised就是proxyFactory,而targetSource持有被代理对象的引用
    TargetSource targetSource = this.advised.targetSource;
    Class<?> targetClass = null;
    Object target = null;
 
    try {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            // 如果当前方法是equals()方法,并且接口中并未定义该方法,就使用自动生成的equals()方法
            return equals(args[0]);
        }
        else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            // 如果当前方法是hashCode()方法,并且接口中并未定义该方法,就使用自动生成的hashCode()方法
            return hashCode();
        } else if (method.getDeclaringClass() == DecoratingProxy.class) {
            // 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型
            return AopProxyUtils.ultimateTargetClass(this.advised);
        } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                method.getDeclaringClass().isAssignableFrom(Advised.class)) {
            // 如果当前方法是Spring织入的Advised接口中的方法,则使用反射调用当前advised对象中的相关方法
            return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
        }
 
        Object retVal;
 
        // 如果设置了需要暴露代理对象,则将当前对象设置到AopContext中
        if (this.advised.exposeProxy) {
            // Make invocation available if necessary.
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        
        // 拿到我们被代理的对象实例
        target = targetSource.getTarget();
        if (target != null) {
            targetClass = target.getClass();
        }
 
        // 获取当前方法需要织入的切面逻辑的调用链
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        
        // 检查我们是否有任何拦截器(advice)。 如果没有,直接反射调用目标,并避免创建MethodInvocation。
        if (chain.isEmpty()) {
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            // 不存在拦截器链,则直接进行反射调用
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        } else {
            // We need to create a method invocation...
            // 如果存在拦截器,则创建一个ReflectiveMethodInvocation:代理对象、被代理对象、方法、参数、
            // 被代理对象的Class、拦截器链作为参数创建ReflectiveMethodInvocation
            invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
            // Proceed to the joinpoint through the interceptor chain.
            // 触发ReflectiveMethodInvocation的执行方法
            retVal = invocation.proceed();
        }
 

        // 必要时转换返回值
        Class<?> returnType = method.getReturnType();
        if (retVal != null && retVal == target &&
                returnType != Object.class && returnType.isInstance(proxy) &&
                !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
            // 判断返回值如果为目标对象,并且当前方法的返回值类型是当前代理对象的类型,那么就将
            // 当前代理对象返回。这里的逻辑的实际意思简单的说就是,如果返回值是目标对象,那么
            // 就将当前代理对象返回
            retVal = proxy;
        } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
            // 如果返回值满足其为空,不是Void类型,并且是基本数据类型,那么就抛出异常,
            // 因为基本数据类型的返回值必然不为空
            throw new AopInvocationException(
                    "Null return value from advice does not match primitive return type for: " + method);
        }
        return retVal;
    } finally {
        if (target != null && !targetSource.isStatic()) {
            // 如果TargetSource不是静态的,则调用其releaseTarget()方法将生成的目标对象释放
            targetSource.releaseTarget(target);
        }
        if (setProxyContext) {
            // 处理AopContext中保存的当前代理对象
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}

        4、ReflectiveMethodInvocation#proceed

        ReflectiveMethodInvocation对象包含代理对象、被代理对象、方法、参数、被代理对象的 Class、拦截器链等。

protected ReflectiveMethodInvocation(
        Object proxy, Object target, Method method, Object[] arguments,
        Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
 
    this.proxy = proxy;
    this.target = target;
    this.targetClass = targetClass;
    this.method = BridgeMethodResolver.findBridgedMethod(method);
    this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
    this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}

        ReflectiveMethodInvocation#proceed()为责任链方法,会按索引执行所有的拦截器。

        如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)。

        如果是一个普通的拦截器,则直接调用它,参数为自己本身。

@Override
public Object proceed() throws Throwable {
    // 1.如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }
    // 2.每次调用时,将索引的值递增,并通过索引拿到要执行的拦截器
    Object interceptorOrInterceptionAdvice =
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    // 3.判断拦截器是否为InterceptorAndDynamicMethodMatcher类型(动态方法匹配拦截器)
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        // 进行动态匹配。在此评估动态方法匹配器:静态部件已经过评估并且发现匹配。
        InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        } else {
            // 动态匹配失败。跳过此拦截器并调用链中的下一个。
            return proceed();
        }
    } else {
        // 4.只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

二、invoke

        1、AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice

        先来看看拦截器链是怎么生成的,getInterceptorsAndDynamicInterceptionAdvice方法取得拦截器链的工作是由配置好的advisorChainFactory来完成的,从名字上可以猜到,它是一个生成通知器链的工厂。在这里,advisorChainFactory被配置成一个DefaultAdivsorChainFactory对象,在DefaultAdivsorChainFactory 中实现了interceptor链的获取过程。

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

        2、DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice

        首先会获取一个AdvisorAdapterRegistry对象,这个对象负责实现拦截器的注册。

        有了AdvisorAdapterRegistry注册器,利用它来从ProxyFactoryBean 配置中得到的通知进行适配,从而获取相应的拦截器,完成所谓的拦截器注册过程。在拦截器适配和注册完成以后,拦截器会被JDK生成AopProxy代理对象的invoke方法或者CGLIB代理对象的intercept拦截方法取得,并启动拦截器的invoke调用,最终触发通知的切面增强。

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {

	List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
	//全局获取AdvisorAdapterRegistry实例
	AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
	for (Advisor advisor : config.getAdvisors()) {
		if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				// 匹配当前方法
				if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
					// 适配advisor成方法拦截器
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					if (mm.isRuntime()) {
						for (MethodInterceptor interceptor : interceptors) {
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						}
					}
					else {
						interceptorList.addAll(Arrays.asList(interceptors));
					}
				}
			}
		}
		else if (advisor instanceof IntroductionAdvisor) {
			IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
			if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}
		else {
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			interceptorList.addAll(Arrays.asList(interceptors));
		}
	}
	return interceptorList;
}

        3、GlobalAdvisorAdapterRegistry

        GlobalAdvisorAdapterRegistry.getInstance()其实就是实例化了一个DefaultAdvisorAdapterRegistry对象。

public abstract class GlobalAdvisorAdapterRegistry {
	private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
	public static AdvisorAdapterRegistry getInstance() {return instance;}
	static void reset() {instance = new DefaultAdvisorAdapterRegistry();}
}

        4、DefaultAdvisorAdapterRegistry

        4.1、DefaultAdvisorAdapterRegistry

        DefaultAdvisorAdapterRegistry对象的构造方法注册了MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter这三个适配器对象。

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
	private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}
	public void registerAdvisorAdapter(AdvisorAdapter adapter) {
		this.adapters.add(adapter);
	}
}

        4.2、getInterceptors

        我们回到上文中的registry.getInterceptors(advisor),该方法也是由这个类实现的。

        可以看出该方法会根据传入的advice增强器是否是MethodInterceptor类型,如果是的话则直接加入集合中,并判断构造方法中注册的适配器是否支持当前的advice,如果支持调用适配器的getInterceptor然后加入到返回集合中。

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
	List<MethodInterceptor> interceptors = new ArrayList<>(3);
	//从Advisor通知配置中取得advice通知
	Advice advice = advisor.getAdvice();
	
	//如果是MethodInterceptor类型,不需要再适配,直接加入集合
	if (advice instanceof MethodInterceptor) {
		interceptors.add((MethodInterceptor) advice);
	}
	// 对adice进行适配
	for (AdvisorAdapter adapter : this.adapters) {
	    //适配器支持当前adive
		if (adapter.supportsAdvice(advice)) {
		    // 适配并返回结果
			interceptors.add(adapter.getInterceptor(advisor));
		}
	}
	if (interceptors.isEmpty()) {
		throw new UnknownAdviceTypeException(advisor.getAdvice());
	}
	return interceptors.toArray(new MethodInterceptor[0]);
}

        以@Before为例,supports方法判断是否为MethodBeforeAdvice类型,是的话则支持。而getInterceptor方法则是把advice从advisor 中取出,然后创建一个MethodBeforeAdviceInterceptor 对象,通过这个对象把advice包装起来,完成适配过程。

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
        // 判断advice增强器是否是MethodBeforeAdvice类型
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

         相关的增强器我们在前文中已经介绍过了,这里不做赘述。

    switch (aspectJAnnotation.getAnnotationType()) {
        case AtBefore:
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
            springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        case AtAround:
            springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtPointcut:
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
    }

        5、invoke

        上文中ReflectiveMethodInvocation#proceed方法中判断如果只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身。

return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

         还是以@Before为例,其invoke方法由于MethodBeforeAdviceInterceptor类实现,该类的invoke方法再调用AspectJMethodBeforeAdvice类的before方法,然后便会执行被增强方法。

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
	private final MethodBeforeAdvice advice;
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}
}

        再比如@After的实现,则是基于MethodInterceptor接口的invoke方法,比如当增强类型为@After时,调用AspectJAfterAdvice的invoke方法,不过这里需要注意的是这里是先return,执行责任链的下一个增强器,最后再执行增强方法invokeAdviceMethod。

    //AspectJAfterAdvice.java
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}

        6、invokeJoinpoint

        invokeJoinpoint负责反射执行连接点,也就是原方法。

protected Object invokeJoinpoint() throws Throwable {
    // 反射执行连接点,也就是原方法,target为被代理的对象实例、method为执行的方法、arguments为方法参数
    return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
 
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
        throws Throwable {
 
    // Use reflection to invoke the method.
    try {
        // 使用反射调用方法
        ReflectionUtils.makeAccessible(method);
        return method.invoke(target, args);
    } catch (InvocationTargetException ex) {
        throw ex.getTargetException();
    } catch (IllegalArgumentException ex) {
        throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
                method + "] on target [" + target + "]", ex);
    } catch (IllegalAccessException ex) {
        throw new AopInvocationException("Could not access method [" + method + "]", ex);
    }
}

        以上,基于@AspectJ注解实现的AOP原理基本介绍完毕,整体流程基本整理如下:

(1)使用<aop:aspectj-autoproxy/>开启AOP注解解析,并注册对应的内部管理的自动代理创建者的 bean:AnnotationAwareAspectJAutoProxyCreator。

(2)容器创建bean到初始化阶段时,调用postProcessAfterInitialization 方法,此时调用此时就会调用我们的 AnnotationAwareAspectJAutoProxyCreator类重写的该方法,然后先查询出所有的增强器(即@Before、@After、@Around 等注解),并根据 @Pointcut 的 execution 表达式筛选出适用于当前遍历的 bean 的增强器, 将适用于当前遍历的 bean 的增强器作为参数之一创建对应的 AOP 代理。

(3)当调用到被 AOP 代理的方法时,会走到对应的代理方法:JdkDynamicAopProxy#invoke 或  DynamicAdvisedInterceptor#intercept,该方法会创建 ReflectiveMethodInvocation,通过责任链的方式来执行所有的增强器和被代理的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值