1. 程式人生 > >springAOP之framework包的解讀(三)

springAOP之framework包的解讀(三)

抽象類 AopProxyUtils

package org.springframework.aop.framework;

import java.util.Arrays;

import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.SingletonTargetSource;
import
org.springframework.util.Assert; /** * AOP代理工廠的工具方法。主要是AOP框架內部使用。 * 檢視AopUtils,一系列通知的AOP工具類方法,不依賴於AOP框架內部。 */ public abstract class AopProxyUtils { /** * 定義給定bean例項的最終目標,不僅貫穿低級別的代理,也包括了任意數量內嵌的代理,對於單例目標,無其他影響 * @param candidate 檢查的例項(可能為aop代理) * @return 目標類(或者給定的類作為後備),不為空 */
public static Class<?> ultimateTargetClass(Object candidate) { Assert.notNull(candidate, "Candidate object must not be null"); Object current = candidate; Class<?> result = null; while (current instanceof TargetClassAware) { result = ((TargetClassAware) current).getTargetClass(); Object nested = null
; if (current instanceof Advised) { TargetSource targetSource = ((Advised) current).getTargetSource(); if (targetSource instanceof SingletonTargetSource) { nested = ((SingletonTargetSource) targetSource).getTarget(); } } current = nested; } if (result == null) { result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass()); } return result; } /** * 根據給定的AOP配置定義全部的代理介面。總是新增Advised介面,除非AdvisedSupport的opaque=true. * 總是新增SpringProxy標誌介面 * @return 全部的代理介面集合 */ public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) { Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces(); if (specifiedInterfaces.length == 0) { // No user-specified interfaces: check whether target class is an interface. Class<?> targetClass = advised.getTargetClass(); if (targetClass != null && targetClass.isInterface()) { specifiedInterfaces = new Class<?>[] {targetClass}; } } boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class); boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class); int nonUserIfcCount = 0; if (addSpringProxy) { nonUserIfcCount++; } if (addAdvised) { nonUserIfcCount++; } Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount]; System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length); if (addSpringProxy) { proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class; } if (addAdvised) { proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class; } return proxiedInterfaces; } /** * 根據給定的代理實現提取使用者指定的介面,例如:所有不是Advised介面的代理實現 * @param proxy 分析的代理(通常是一個JDK動態代理) * @return 所有使用者指定的代理實現介面,按照原先的順序,不為空。 */ public static Class<?>[] proxiedUserInterfaces(Object proxy) { Class<?>[] proxyInterfaces = proxy.getClass().getInterfaces(); int nonUserIfcCount = 0; if (proxy instanceof SpringProxy) { nonUserIfcCount++; } if (proxy instanceof Advised) { nonUserIfcCount++; } Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount]; System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length); Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces"); return userInterfaces; } /** * 檢查AdvisedSupport物件的代理是否相等。不符合以下條件的AdvisedSupport物件不相等:介面、advisors、目標源都要相等 */ public static boolean equalsInProxy(AdvisedSupport a, AdvisedSupport b) { return (a == b || (equalsProxiedInterfaces(a, b) && equalsAdvisors(a, b) && a.getTargetSource().equals(b.getTargetSource()))); } /** * 檢查AdvisedSupport物件的代理介面是否相等 */ public static boolean equalsProxiedInterfaces(AdvisedSupport a, AdvisedSupport b) { return Arrays.equals(a.getProxiedInterfaces(), b.getProxiedInterfaces()); } /** * 檢查AdvisedSupport物件的顧問(advisors)是否相等 */ public static boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b) { return Arrays.equals(a.getAdvisors(), b.getAdvisors()); } }

類CglibAopProxy

package org.springframework.aop.framework;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.aop.Advisor;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.cglib.core.CodeGenerationException;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
import org.springframework.core.SmartClassLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

/**
 * springAOP框架中基於CGLIB的AopProxy實現類
 * 原先命名為Cglib2AopProxy,在spring3.2中,該類依賴於spring內部,需要重新打包CGLIB3
 * 該型別的物件必須通過代理工廠獲取,根據AdvisedSupport物件的配置。該類是springAOP框架內部的,不能直接用於客戶端。 
 * 如果需要,DefaultAopProxyFactory會自動建立基於CGLIB的代理,例如,代理目標類。
 * 當目標是執行緒安全的,那麼用該類建立的代理也是執行緒安全的。
 */
@SuppressWarnings("serial")
class CglibAopProxy implements AopProxy, Serializable {

    // CGLIB回撥的陣列的索引
    private static final int AOP_PROXY = 0;
    private static final int INVOKE_TARGET = 1;
    private static final int NO_OVERRIDE = 2;
    private static final int DISPATCH_TARGET = 3;
    private static final int DISPATCH_ADVISED = 4;
    private static final int INVOKE_EQUALS = 5;
    private static final int INVOKE_HASHCODE = 6;


    /** Logger available to subclasses; static to optimize serialization */
    protected final static Log logger = LogFactory.getLog(CglibAopProxy.class);

    /** 保持跟蹤那些final方法已驗證的類 */
    private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap<Class<?>, Boolean>();


    /** 代理的配置 */
    protected final AdvisedSupport advised;

    private Object[] constructorArgs;

    private Class<?>[] constructorArgTypes;

    /** 通知介面方法的呼叫 */
    private final transient AdvisedDispatcher advisedDispatcher;

    private transient Map<String, Integer> fixedInterceptorMap;

    private transient int fixedInterceptorOffset;


    /**
     * 用給的AOP配置建立新的CglibAopProxy。
     * @param config AOP配置物件
     * @throws AopConfigException 當配置無效,我們丟擲提供相關資訊的異常,而不是未知的失敗
     */
    public CglibAopProxy(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;
        this.advisedDispatcher = new AdvisedDispatcher(this.advised);
    }

    /**
     * 設定建立代理的構造引數
     */
    public void setConstructorArguments(Object[] constructorArgs, Class<?>[] constructorArgTypes) {
        if (constructorArgs == null || constructorArgTypes == null) {
            throw new IllegalArgumentException("Both 'constructorArgs' and 'constructorArgTypes' need to be specified");
        }
        if (constructorArgs.length != constructorArgTypes.length) {
            throw new IllegalArgumentException("Number of 'constructorArgs' (" + constructorArgs.length +
                    ") must match number of 'constructorArgTypes' (" + constructorArgTypes.length + ")");
        }
        this.constructorArgs = constructorArgs;
        this.constructorArgTypes = constructorArgTypes;
    }


    @Override
    public Object getProxy() {
        return getProxy(null);
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

            Class<?> proxySuperClass = rootClass;
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                for (Class<?> additionalInterface : additionalInterfaces) {
                    this.advised.addInterface(additionalInterface);
                }
            }

            // Validate the class, writing log messages as necessary.
            validateClassIfNecessary(proxySuperClass, classLoader);

            // Configure CGLIB Enhancer...
            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 UndeclaredThrowableStrategy(UndeclaredThrowableException.class));

            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);
        }
        catch (CodeGenerationException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" +
                    this.advised.getTargetClass() + "]: " +
                    "Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }
        catch (IllegalArgumentException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" +
                    this.advised.getTargetClass() + "]: " +
                    "Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }
        catch (Exception ex) {
            // TargetSource.getTarget() failed
            throw new AopConfigException("Unexpected AOP exception", ex);
        }
    }

    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        enhancer.setInterceptDuringConstruction(false);
        enhancer.setCallbacks(callbacks);
        return (this.constructorArgs != null ?
                enhancer.create(this.constructorArgTypes, this.constructorArgs) :
                enhancer.create());
    }

    /**
     * 建立CGLIB的增強。子類可能會重寫,可返回自定義的增強的實現
     */
    protected Enhancer createEnhancer() {
        return new Enhancer();
    }

    /**
     * 提供的類是否已驗證,若沒有,驗證它。
    private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
        if (logger.isInfoEnabled()) {
            synchronized (validatedClasses) {
                if (!validatedClasses.containsKey(proxySuperClass)) {
                    doValidateClass(proxySuperClass, proxyClassLoader);
                    validatedClasses.put(proxySuperClass, Boolean.TRUE);
                }
            }
        }
    }

    /**
     * 檢查給定類的方法,包括類載入器的包可見方法。
     */
    private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
        if (!Object.class.equals(proxySuperClass)) {
            Method[] methods = proxySuperClass.getDeclaredMethods();
            for (Method method : methods) {
                int mod = method.getModifiers();
                if (!Modifier.isStatic(mod)) {
                    if (Modifier.isFinal(mod)) {
                        logger.info("Unable to proxy method [" + method + "] because it is final: " +
                                "All calls to this method via a proxy will NOT be routed to the target instance.");
                    }
                    else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&
                            proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
                        logger.info("Unable to proxy method [" + method + "] because it is package-visible " +
                                "across different ClassLoaders: All calls to this method via a proxy will " +
                                "NOT be routed to the target instance.");
                    }
                }
            }
            doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader);
        }
    }

    private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
        // 用於優化的引數 
        boolean exposeProxy = this.advised.isExposeProxy();
        boolean isFrozen = this.advised.isFrozen();
        boolean isStatic = this.advised.getTargetSource().isStatic();

        // 選擇一個aop攔截器(用於Aopr的呼叫)
        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

        // 選擇一個直接的目標攔截器。(未通知的呼叫,可以返回)。可能需要暴露代理
        Callback targetInterceptor;
        if (exposeProxy) {
            targetInterceptor = isStatic ?
                    new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                    new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
        }
        else {
            targetInterceptor = isStatic ?
                    new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                    new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
        }

        // 選擇一個介面的目標排程者(用於未通知的靜態目標,無法返回
        Callback targetDispatcher = isStatic ?
                new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();

        Callback[] mainCallbacks = new Callback[]{
            aopInterceptor, // for normal advice
            targetInterceptor, // invoke target without considering advice, if optimized
            new SerializableNoOp(), // no override for methods mapped to this
            targetDispatcher, this.advisedDispatcher,
            new EqualsInterceptor(this.advised),
            new HashCodeInterceptor(this.advised)
        };

        Callback[] callbacks;

        //如果目標是靜態的,且通知鏈是凍結的,我們可以直接呼叫固定鏈的目標進行優化
        if (isStatic && isFrozen) {
            Method[] methods = rootClass.getMethods();
            Callback[] fixedCallbacks = new Callback[methods.length];
            this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);


            // 優化記憶體(跳過沒有通知的方法建立)
            for (int x = 0; x < methods.length; x++) {
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
                fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                        chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
                this.fixedInterceptorMap.put(methods[x].toString(), x);
            }

            // 將主要的回撥和混合的回撥複製到回撥陣列
            callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
            System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
            System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
            this.fixedInterceptorOffset = mainCallbacks.length;
        }
        else {
            callbacks = mainCallbacks;
        }
        return callbacks;
    }

    /**
     * 處理返回值。如果需要,處理返回值成為代理,為null不返回原始型別
     */
    private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
        // Massage return value if necessary
        if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
            // Special case: it returned "this". Note that we can't help
            // if the target sets a reference to itself in another returned object.
            retVal = proxy;
        }
        Class<?> returnType = method.getReturnType();
        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;
    }


    @Override
    public boolean equals(Object other) {
        return (this == other || (other instanceof CglibAopProxy &&
                AopProxyUtils.equalsInProxy(this.advised, ((CglibAopProxy) other).advised)));
    }

    @Override
    public int hashCode() {
        return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
    }


    /**
     * 替代CGLIB的 NoOp介面
     */
    public static class SerializableNoOp implements NoOp, Serializable {
    }


    /**
     * 用於沒有通知鏈的靜態目標的方法攔截器。呼叫直接傳到目標物件。當代理需要暴露使用,不能決定方法會返回
     */
    private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {

        private final Object target;

        public StaticUnadvisedInterceptor(Object target) {
            this.target = target;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object retVal = methodProxy.invoke(this.target, args);
            return processReturnType(proxy, this.target, method, retVal);
        }
    }


    /**
     * 當代理需要暴露,用於沒有通知鏈的靜態目標的方法攔截器。
     */
    private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

        private final Object target;

        public StaticUnadvisedExposedInterceptor(Object target) {
            this.target = target;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            try {
                oldProxy = AopContext.setCurrentProxy(proxy);
                Object retVal = methodProxy.invoke(this.target, args);
                return processReturnType(proxy, this.target, method, retVal);
            }
            finally {
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }


    /**
     * 該攔截器就可以呼叫的動態目標,該目標不需要建立方法呼叫或評估通知鏈。(我們知道沒有這個方法的通知)
     */
    private static class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {

        private final TargetSource targetSource;

        public DynamicUnadvisedInterceptor(TargetSource targetSource) {
            this.targetSource = targetSource;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object target = this.targetSource.getTarget();
            try {
                Object retVal = methodProxy.invoke(target, args);
                return processReturnType(proxy, target, method, retVal);
            }
            finally {
                this.targetSource.releaseTarget(target);
            }
        }
    }


    /**
     * 攔截器用於無通知的動態目標,該目標代理需要暴露
     */
    private static class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

        private final TargetSource targetSource;

        public DynamicUnadvisedExposedInterceptor(TargetSource targetSource) {
            this.targetSource = targetSource;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            Object target = this.targetSource.getTarget();
            try {
                oldProxy = AopContext.setCurrentProxy(proxy);
                Object retVal = methodProxy.invoke(target, args);
                return processReturnType(proxy, target, method, retVal);
            }
            finally {
                AopContext.setCurrentProxy(oldProxy);
                this.targetSource.releaseTarget(target);
            }
        }
    }


    /**
     * 靜態目標的排程者。排程者比攔截器更快。當一個方法明確地不會返回"this"時使用。
     */
    private static class StaticDispatcher implements Dispatcher, Serializable {

        private Object target;

        public StaticDispatcher(Object target) {
            this.target = target;
        }

        @Override
        public Object loadObject() {
            return this.target;
        }
    }


    /**
     * 通知類的任何宣告的方法的排程者
     * Dispatcher for any methods declared on the Advised class.
     */
    private static class AdvisedDispatcher implements Dispatcher, Serializable {

        private final AdvisedSupport advised;

        public AdvisedDispatcher(AdvisedSupport advised) {
            this.advised = advised;
        }

        @Override
        public Object loadObject() throws Exception {
            return this.advised;
        }
    }


    /**
     * 相等方法的攔截器,確保方法的呼叫總是用這個類處理
     */
    private static class EqualsInterceptor implements MethodInterceptor, Serializable {

        private final AdvisedSupport advised;

        public EqualsInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
            Object other = args[0];
            if (proxy == other) {
                return true;
            }
            if (other instanceof Factory) {
                Callback callback = ((Factory) other).getCallback(INVOKE_EQUALS);
                if (!(callback instanceof EqualsInterceptor)) {
                    return false;
                }
                AdvisedSupport otherAdvised = ((EqualsInterceptor) callback).advised;
                return AopProxyUtils.equalsInProxy(this.advised, otherAdvised);
            }
            else {
                return false;
            }
        }
    }


    /**
     * hashCode方法的攔截器,確保方法的呼叫總是用這個類處理
     */
    private static class HashCodeInterceptor implements MethodInterceptor, Serializable {

        private final AdvisedSupport advised;

        public HashCodeInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
            return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
        }
    }


    /**
     * 攔截器,明確的用於通知方法,在凍結的、靜態的代理物件裡
     */
    private static class FixedChainStaticTargetInterceptor implements MethodInterceptor, Serializable {

        private final List<Object> adviceChain;

        private final Object target;

        private final Class<?> targetClass;

        public FixedChainStaticTargetInterceptor(List<Object> adviceChain, Object target, Class<?> targetClass) {
            this.adviceChain = adviceChain;
            this.target = target;
            this.targetClass = targetClass;
        }

        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args,
                    this.targetClass, this.adviceChain, methodProxy);
            // If we get here, we need to create a MethodInvocation.
            Object retVal = invocation.proceed();
            retVal = processReturnType(proxy, this.target, method, retVal);
            return retVal;
        }
    }


    /**
     * 通用的AOP回撥。當目標是動態的或者代理沒被凍結時使用
     */
    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

        private final AdvisedSupport advised;

        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }

        @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.
                    retVal = methodProxy.invoke(target, args);
                }
                else {
                    // 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) {
                    releaseTarget(target);
                }
                if (setProxyContext) {
                    // Restore old proxy.
                    AopContext.setCurrentProxy(oldProxy);
                }
            }
        }

        @Override
        public boolean equals(Object other) {
            return (this == other ||
                    (other instanceof DynamicAdvisedInterceptor &&
                            this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
        }

        /**
         * CGLIB uses this to drive proxy creation.
         */
        @Override
        public int hashCode() {
            return this.advised.hashCode();
        }

        protected Object getTarget() throws Exception {
            return this.advised.getTargetSource().getTarget();
        }

        protected void releaseTarget(Object target) throws Exception {
            this.advised.getTargetSource().releaseTarget(target);
        }
    }


    /**
     * AOP框架方法呼叫的實現,通過aop代理
     */
    private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

        private final MethodProxy methodProxy;

        private final boolean publicMethod;

        public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
                Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
            super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
            this.methodProxy = methodProxy;
            this.publicMethod = Modifier.isPublic(method.getModifiers());
        }

        /**
         * 提供一個臨界的效能提升,與呼叫的反射相對抗,當呼叫公開的方法時。
         */
        @Override
        protected Object invokeJoinpoint() throws Throwable {
            if (this.publicMethod) {
                return this.methodProxy.invoke(this.target, this.arguments);
            }
            else {
                return super.invokeJoinpoint();
            }
        }
    }


    /**
     * 回撥過濾
     */
    private static class ProxyCallbackFilter implements CallbackFilter {

        private final AdvisedSupport advised;

        private final Map<String, Integer> fixedInterceptorMap;

        private final int fixedInterceptorOffset;

        public ProxyCallbackFilter(AdvisedSupport advised, Map<String, Integer> fixedInterceptorMap, int fixedInterceptorOffset) {
            this.advised = advised;
            this.fixedInterceptorMap = fixedInterceptorMap;
            this.fixedInterceptorOffset = fixedInterceptorOffset;
        }

        /**
         * CallbackFilter.accept()的實現,返回我們需要回調的下標。
         * 每個代理的回撥由一系列的固定的回撥組成,這些回撥是通用的,並且對一個方法是具體的,該方法用於固定的通知鏈的靜態目標
         * 回撥的使用由以下決定:
         * 1.對於暴露的代理,暴露的代理,需要程式碼在方法/鏈呼叫的之前與之後執行,
         * 這意味著我們必須使用DynamicAdvisedInterceptor,自從其他的攔截器能避免try/catch塊。
         * 2.對於Object.finalize():方法無重寫會被使用。
         * 3.對於equals():EqualsInterceptor會被使用,重新呼叫equals(),對於該代理的一個特定的處理器。
         * 4.對於通知類的方法:AdvisedDispatcher會被使用,用來排程目標的直接呼叫。
         * 5.對於通知方法:如果目標是靜態的,通知鏈是凍結的,那麼FixedChainStaticTargetInterceptor關於該具體的方法會用於呼叫通知鏈,
         *   否則使用DyanmicAdvisedInterceptor
         * 6.對於未通知的方法:可以確定該方法將不會返回this,或者ProxyFactory.getExposeProxy()返回false
         *   Dispatcher會被使用。對於靜態的目標,使用StaticDispatcher,對於動態的目標,使用DynamicUnadvisedInterceptor.
         *   該方法有可能返回this,StaticUnadvisedInterceptor就會用於靜態的目標,DynamicUnadvisedInterceptor已經考慮到這種情況。
         * </dl>
         */
        @Override
        public int accept(Method method) {
            if (AopUtils.isFinalizeMethod(method)) {
                logger.debug("Found finalize() method - using NO_OVERRIDE");
                return NO_OVERRIDE;
            }
            if (!this.advised.isOpaque() && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Method is declared on Advised interface: " + method);
                }
                return DISPATCH_ADVISED;
            }
            // We must always proxy equals, to direct calls to this.
            if (AopUtils.isEqualsMethod(method)) {
                logger.debug("Found 'equals' method: " + method);
                return INVOKE_EQUALS;
            }
            // We must always calculate hashCode based on the proxy.
            if (AopUtils.isHashCodeMethod(method)) {
                logger.debug("Found 'hashCode' method: " + method);
                return INVOKE_HASHCODE;
            }
            Class<?> targetClass = this.advised.getTargetClass();
            // Proxy is not yet available, but that shouldn't matter.
            List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            boolean haveAdvice = !chain.isEmpty();
            boolean exposeProxy = this.advised.isExposeProxy();
            boolean isStatic = this.advised.getTargetSource().isStatic();
            boolean isFrozen = this.advised.isFrozen();
            if (haveAdvice || !isFrozen) {
                // If exposing the proxy, then AOP_PROXY must be used.
                if (exposeProxy) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Must expose proxy on advised method: " + method);
                    }
                    return AOP_PROXY;
                }
                String key = method.toString();
                // Check to see if we have fixed interceptor to serve this method.
                // Else use the AOP_PROXY.
                if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Method has advice and optimisations are enabled: " + method);
                    }
                    // We know that we are optimising so we can use the
                    // FixedStaticChainInterceptors.
                    int index = this.fixedInterceptorMap.get(key);
                    return (index + this.fixedInterceptorOffset);
                }
                else {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Unable to apply any optimisations to advised method: " + method);
                    }
                    return AOP_PROXY;
                }
            }
            else {
                // See if the return type of the method is outside the class hierarchy
                // of the target type. If so we know it never needs to have return type
                // massage and can use a dispatcher.
                // If the proxy is being exposed, then must use the interceptor the