Spring AOP ProxyFactoryBean源码笔记 二

AopProxy getProxy()方法获取到的代理分为Jdk代理JdkDynamicAopProxy或者Cglib代理ObjenesisCglibAopProxy。代理在生成代理对象时,设置了对应的回调入口。

  • Jdk是JdkDynamicAopProxy中用Proxy.newProxyInstance来生成代理对象,对应的回调入口为JdkDynamicAopProxy invoke()方法。
  • Cglib是在ObjenesisCglibAopProxy的父类CglibAopProxy中配置了Enhancer来创建代理对象, Enhancer上的回调为 DynamicAdvisedInterceptor, 实际的回调入口为DynamicAdvisedInterceptor intercept()方法

代理类的调用过程:

  • Jdk的回调 JdkDynamicAopProxy invoke()
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
...
    // 顺序1 
    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");
        }
        this.advised = config;
    }
...
@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;
        // 顺序1 
        // 在创建Jdk代理的时候,调用了JdkDynamicAopProxy的构造器,new JdkDynamicAopProxy(config)。
        // config即ProxyFactoryBean,保存在JdkDynamicAopProxy的advised属性上。
        // 从ProxyFactoryBean上获取包装后的目标对象
        TargetSource targetSource = this.advised.targetSource;
        Class targetClass = null;
        Object target = null;

        try {
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // The target does not implement the equals(Object) method itself.
                return equals(args[0]);
            }
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                // The target does not implement the hashCode() method itself.
                return hashCode();
            }
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                // There is only getDecoratedClass() declared -> dispatch to proxy config.
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                // Service invocations on ProxyConfig with the proxy config...
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;

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

            // May be null. Get as late as possible to minimize the time we "own" the target,
            // in case it comes from a pool.
            // 真正的目标对象
            target = targetSource.getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }

            // Get the interception chain for this method.
            // 顺序2
            // 获取拦截器链
            // 调用的是JdkDynamicAopProxy的基类AdvisedSupport的getInterceptorsAndDynamicInterceptionAdvice()方法
            List 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()) {
                // 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 = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // We need to create a method invocation...
                // 顺序6
                // 构造ReflectiveMethodInvocation
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                // 顺序7
                // 调用proceed方法
                retVal = invocation.proceed();
            }

            // Massage return value if necessary.
            Class returnType = method.getReturnType();
            if (retVal != null && retVal == target &&
                    returnType != Object.class && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                // Special case: it returned "this" and the return type of the method
                // is type-compatible. Note that we can't help if the target sets
                // a reference to itself in another returned object.
                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;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                // Must have come from TargetSource.
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }
 
 

AdvisedSupport getInterceptorsAndDynamicInterceptionAdvice()

public class AdvisedSupport extends ProxyConfig implements Advised {
...
    AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
...
    private transient Map> methodCache;
...
    private void initMethodCache() {
        this.methodCache = new ConcurrentHashMap>(32);
    }
...
    // 顺序2
    public List getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        // 尝试从缓存中获取拦截器
        List cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            // 顺序3
            // 如果缓存中获取不到
            // this.advisorChainFactory为DefaultAdvisorChainFactory,进入其getInterceptorsAndDynamicInterceptionAdvice()方法
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }
 
 

DefaultAdvisorChainFactory getInterceptorsAndDynamicInterceptionAdvice()

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
...
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
...
    // 顺序3
    @Override
    public List getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, Class targetClass) {

        // This is somewhat tricky... We have to process introductions first,
        // but we need to preserve order in the ultimate list.
        List interceptorList = new ArrayList(config.getAdvisors().length);
        Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        // 遍历通知器
        for (Advisor advisor : config.getAdvisors()) {
            if (advisor instanceof PointcutAdvisor) {
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                // DefaultPointcutAdvisor的matches()始终返回true
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    // 顺序4
                    // 获取当前通知器的所有拦截器。一个通知器可能前置、后置和异常多个拦截器
                    // registry为GlobalAdvisorAdapterRegistry.getInstance();
                    // 在上一篇ProxyFactoryBean初始化过程中,已经创建了DefaultAdvisorAdapterRegistry
                    // 并在其构造器中初始化了前置、后置和异常通知适配器
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    // 拿到通知器的切点 再根据切点拿到方法匹配规则
                    // demo中的通知器类型均为DefaultPointcutAdvisor,匹配规则始终为true(所有方法均匹配)
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            // Creating a new object instance in the getInterceptors() method
                            // isn't a problem as we normally cache created chains.
                            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;
    }

    private static boolean hasMatchingIntroductions(Advised config, Class actualClass) {
        for (int i = 0; i < config.getAdvisors().length; i++) {
            Advisor advisor = config.getAdvisors()[i];
            if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (ia.getClassFilter().matches(actualClass)) {
                    return true;
                }
            }
        }
        return false;
    }
 
 

DefaultAdvisorAdapterRegistry getInterceptors()

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
...
    // 顺序4
    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List interceptors = new ArrayList(3);
        // 从通知器中取出通知
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            // 逐个适配器判断是否适配当前通知
            // 一个通知也可以同时适配多个适配器。例如一个类同时实现前置与后置拦截器的接口
            if (adapter.supportsAdvice(advice)) {
                // 顺序5
                // 如果适配,用适配器与通知器构造对应的拦截器
                // 例如AfterReturningAdviceInterceptor后置适配器
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        // 最终返回所有拦截器
        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
    }

AfterReturningAdviceAdapter

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
...
    // 顺序5 构造后置拦截器 返回顺序2
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
        return new AfterReturningAdviceInterceptor(advice);
    }

ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
...
    // 顺序6
    protected ReflectiveMethodInvocation(
            Object proxy, Object target, Method method, Object[] arguments,
            Class targetClass, List interceptorsAndDynamicMethodMatchers) {

        this.proxy = proxy;
        this.target = target;
        this.targetClass = targetClass;
        this.method = BridgeMethodResolver.findBridgedMethod(method);
        this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
    }
...
    // 顺序7
    @Override
    public Object proceed() throws Throwable {
        //  We start with an index of -1 and increment early.
// 如果已经执行完所有拦截器,执行目标方法
        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.
            // 在目标方法执行前
            // 获取到拦截器链上的第一个拦截器
            // 如果是前置拦截器,先执行前置拦截器的逻辑,然后执行目标方法(参考下面MethodBeforeAdviceInterceptor中的invoke()方法),此时并不是真正的执行目标方法,而是继续进入到ReflectiveMethodInvocation的proceed() 方法,获取下一个拦截器。
            // 如果是后置拦截器,先执行目标方法(参考下面AfterReturningAdviceInterceptor中的invoke()方法),同样进入到proceed() 方法,获取下一个拦截器,待执行完下一个拦截器,再回来执行后置逻辑。
            // 依次循环,直到所有的拦截器执行完,最终执行目标方法。
            // 总的来说是所有前置拦截器中前置逻辑先执行,然后执行目标方法,最后执行所有后置拦截器的后置逻辑再执行。
            // 异常拦截器的逻辑相似,用try catch包裹了目标方法的执行,在出现异常时执行织入的异常逻辑,然后将异常向上抛出。
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
 
 

MethodBeforeAdviceInterceptor invoke()

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        // 通知的before方法先执行 再执行目标方法
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
        return mi.proceed();
    }

AfterReturningAdviceInterceptor invoke()

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        // 待目标方法执行完成,再执行通知的after方法
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
  • Cglib的回调 DynamicAdvisedInterceptor intercept()
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
...
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Class targetClass = null;
            Object target = null;
            try {
                if (this.advised.exposeProxy) {
                    // Make invocation available if necessary.
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
                // May be null. Get as late as possible to minimize the time we
                // "own" the target, in case it comes from a pool...
                target = getTarget();
                if (target != null) {
                    targetClass = target.getClass();
                }
                // 同上 获取拦截器链
                List 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 {
                    // We need to create a method invocation...
                    // 构造CglibMethodInvocation,然后执行proceed()方法。CglibMethodInvocation是ReflectiveMethodInvocation的子类,还是执行了ReflectiveMethodInvocation的proceed()方法,同上。
                    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
                }
                retVal = processReturnType(proxy, target, method, retVal);
                return retVal;
            }
            finally {
                if (target != null) {
                    releaseTarget(target);
                }
                if (setProxyContext) {
                    // Restore old proxy.
                    AopContext.setCurrentProxy(oldProxy);
                }
            }
        }
 
 

总结:

  • 初始化通知器,将对ProxyFactory配置的所有通知(也可以是通知器)收集起来,即为目标对象配置的所有通知收集起来。
  • 根据目标对象创建代理,Jdk代理或者Cglib代理。
  • 根据代理创建代理对象,在创建代理对象时设置回调入口。
  • 对目标方法的调用,实际是调用了代理对象的回调方法。例如JdkDynamicAopProxy invoke()DynamicAdvisedInterceptor intercept()
  • 拿到初始化中收集的通知器,从通知器中拿到切点,切点中再拿到方法匹配器,根据匹配规则,将应该为当前方法做的增强收集起来
  • 最终构造ReflectiveMethodInvocation对象,执行proceed()方法,先执行收集起来的前置通知,再执行目标方法,最后执行收集起来的后置通知。如果在目标方法执行过程中有发生异常,会执行收集的异常通知,再将异常向上抛出。

你可能感兴趣的:(Spring AOP ProxyFactoryBean源码笔记 二)