美文网首页AOP(面向切面编程)Spring源码分析
Spring AOP ProxyFactoryBean源码笔记

Spring AOP ProxyFactoryBean源码笔记

作者: 丶含光 | 来源:发表于2019-08-08 01:02 被阅读0次

    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<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()) {
                    // 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<MethodCacheKey, List<Object>> methodCache;
    ...
        private void initMethodCache() {
            this.methodCache = new ConcurrentHashMap<MethodCacheKey, List<Object>>(32);
        }
    ...
        // 顺序2
        public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
            MethodCacheKey cacheKey = new MethodCacheKey(method);
            // 尝试从缓存中获取拦截器
            List<Object> 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<Object> 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<Object> interceptorList = new ArrayList<Object>(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<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(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<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;
        }
    ...
        // 顺序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<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 {
                        // 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源码笔记

        本文链接:https://www.haomeiwen.com/subject/gjhudctx.html