spring--aop_1_源碼分析之JdkDynamicAopProxy實(shí)現(xiàn)

aop 實(shí)現(xiàn)有兩種方式

  1. ProxyFactoryBean方式: 這種方式是通過配置實(shí)現(xiàn)
  2. ProxyFactory方式:這種方式是通過編程實(shí)現(xiàn)

這里說 ProxyFactoryBean ,先上一張ProxyFactoryBean 的關(guān)系圖,后面能用到。

示例代碼:

/**

  • 代理接口,如果不是接口使用CGLIB代理
    /
    public interface ProxyInterface {
    void m();
    void t();
    }
    /
    *

  • 目標(biāo)對(duì)象,接口的實(shí)現(xiàn)類
    */
    public class Target implements ProxyInterface {
    @Override
    public void m() {
    System.out.println("m");
    }

    @Override
    public void t() {
    System.out.println("t");
    }
    }

/**

  • 通知器
    /
    public class BeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
    System.out.println("BeforeAdvice.....");
    }
    }
    /
    *
  • 通知器
    */
    public class AfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println("AfterAdvice.....");
    }
    }
    定義一個(gè)接口ProxyInterface, 實(shí)現(xiàn)類為 Target,聲明了兩個(gè)advice,用來增強(qiáng)Target 方法。配置文件如下(advice 配置的順序就是調(diào)用的順序):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<!-- 目標(biāo)類 -->
<bean id="target" class="com.masz.springtest.aop.proxy.Target"/>

<!-- advice -->
<bean id="beforeAdvice" class="com.masz.springtest.aop.proxy.BeforeAdvice"/>
<bean id="afterAdvice" class="com.masz.springtest.aop.proxy.AfterAdvice"/>

<!-- 增強(qiáng)代理對(duì)象,ProxyFactoryBean 是一個(gè)FactoryBean , getBean() 時(shí)會(huì)調(diào)用它的getObject() 方法 -->
<bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <!-- 代理接口,如果沒有接口使用CGLIB生成代理類-->
    <property name="proxyInterfaces">
        <list>
            <value>com.masz.springtest.aop.proxy.ProxyInterface</value>
        </list>
    </property>
    <property name="singleton" value="true"/>  <!-- 是否是單例 -->
    <property name="target" ref="target"/>  <!-- 指定增強(qiáng)目標(biāo)bean -->

    <!-- 攔截器名稱 -->
    <property name="interceptorNames">
        <list>
            <value>beforeAdvice</value>
            <value>afterAdvice</value>
        </list>
    </property>
</bean>

</beans>
測(cè)試:

public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(AopTest.class, args);

//直接獲取目標(biāo)類
Target t = applicationContext.getBean(Target.class);
t.m();

//獲取目標(biāo)的代理。 關(guān)鍵的是:ProxyFactoryBean  是一個(gè)FactoryBean
ProxyInterface  proxy = (ProxyInterface)applicationContext.getBean("targetProxy");
proxy.m();
System.exit(0);

}
運(yùn)行結(jié)果:

m
BeforeAdvice.....
m
AfterAdvice.....

第一個(gè)方法沒有被增強(qiáng),第二個(gè)方法被增強(qiáng)了。

源碼分析:

從代碼中可以看到,通過applicationContext.getBean()獲取ProxyFactoryBean, ProxyFactoryBean 是一個(gè)FactoryBean 所以getObject() 方法就是獲取代理對(duì)象的入口方法。

ProxyFactoryBean.getObject() 源碼:

@Override
@Nullable
public Object getObject() throws BeansException {
//初始化advisor 鏈
initializeAdvisorChain();

//對(duì)singleton 和 prototype 類型區(qū)分,生成相應(yīng)的proxy
if (isSingleton()) {
    //是singleton,調(diào)用此方法生成代理對(duì)象
    return getSingletonInstance();
}
else {
    if (this.targetName == null) {
        logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
                "Enable prototype proxies by setting the 'targetName' property.");
    }
    //不是singleton,創(chuàng)建一個(gè)Prototype 的實(shí)例的代理對(duì)象
    return newPrototypeInstance();
}

}
initializeAdvisorChain() 初始化 advisor chain:

/**

  • 創(chuàng)建advisor 鏈。
  • advisor 信息從BeanFactory 來的,每當(dāng)創(chuàng)建一個(gè)新的prototype實(shí)例被創(chuàng)建時(shí),BeanFactory 就會(huì)被刷新。
  • 攔截器通過factory api 以編程的方式被添加,而且不受advisor改變的影響。

過程:
這個(gè)初始化advisor 鏈,是應(yīng)用第一次通過 ProxyFactoryBean 獲取代理對(duì)象時(shí)觸發(fā)的,
advisor 鏈初始化完成之后,會(huì)讀取配置中所有的通知器,這個(gè)讀取比較簡(jiǎn)單就是調(diào)用容器的getBean()方法;
然后把獲取的advice 加入到 advisor 鏈中,這個(gè)過程是addAdvisorOnChainCreation() 方法實(shí)現(xiàn)

*/
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//這個(gè)是個(gè)標(biāo)識(shí)位,標(biāo)記通知器鏈?zhǔn)欠褚呀?jīng)初始化過了,如果已經(jīng)初始化完了就直接返回。
if (this.advisorChainInitialized) {
return;
}

//配置的advice 不能是空的,如果沒有配置advice就不用增強(qiáng)了。
if (!ObjectUtils.isEmpty(this.interceptorNames)) {

    //所有的bean 都是BeanFactory 管理的,所以BeanFactory不能是空
    if (this.beanFactory == null) {
        throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
    }

    // Globals can't be last unless we specified a targetSource using the property...
    if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
            this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
        throw new AopConfigException("Target required after globals");
    }

    //遍歷所有的advice 名稱配置,獲取advice bean 并且添加到 advisor 鏈
    for (String name : this.interceptorNames) {
        if (logger.isTraceEnabled()) {
            logger.trace("Configuring advisor or advice '" + name + "'");
        }

        //interceptor name 是 * 結(jié)尾的
        if (name.endsWith(GLOBAL_SUFFIX)) {
            if (!(this.beanFactory instanceof ListableBeanFactory)) {
                throw new AopConfigException(
                        "Can only use global advisors or interceptors with a ListableBeanFactory");
            }
            addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                    name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
        }

        else {
            // If we get here, we need to add a named interceptor.
            // We must check if it's a singleton or prototype.
            //程序運(yùn)行到這里就要檢查添加的 interceptor 是 singleton 還是 prototype 類型。
            
            Object advice;
            if (this.singleton || this.beanFactory.isSingleton(name)) {
                // Add the real Advisor/Advice to the chain.
                //單例的 advice,就從beanFactory 中g(shù)et bean 了。
                advice = this.beanFactory.getBean(name);
            }
            else {
                // It's a prototype Advice or Advisor: replace with a prototype.
                // Avoid unnecessary creation of prototype bean just for advisor chain initialization.
                //prototype advice,要?jiǎng)?chuàng)建一個(gè)新的advice
                advice = new PrototypePlaceholderAdvisor(name);
            }
            //添加advice 到 advisor chain
            addAdvisorOnChainCreation(advice, name);
        }
    }
}
this.advisorChainInitialized = true;

}
上面方法中的 addAdvisorOnChainCreation() 方法:
把配置 advice 封裝成一個(gè) DefaultPointcutAdvisor 對(duì)象,包含了PointCut(默認(rèn)是Pointcut.TRUE) 和 advice。
然后把封裝成的 advisor 放到 advisors 集合中,這個(gè)過程是在 類AdvisedSupport 中實(shí)現(xiàn)的,ProxyFactoryBean 是這個(gè)類的子類,看上圖。

getSingletonInstance() 方法, 生成 singleton 代理對(duì)象。

/**

  • Return the singleton instance of this class's proxy object,
  • lazily creating it if it hasn't been created already.
  • @return the shared singleton proxy

返回一個(gè)單例的代理對(duì)象,如果沒有創(chuàng)建則會(huì)進(jìn)行懶加載。

過程:首先讀取ProxyFactoryBean 的配置,為生成代理對(duì)象做好準(zhǔn)備,如:代理接口,目錄對(duì)象等。
再通過AopProxy 生成代理對(duì)象。

*/
private synchronized Object getSingletonInstance() {
//如果已經(jīng)創(chuàng)建了,就直接返回
if (this.singletonInstance == null) {

    this.targetSource = freshTargetSource();
    if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
        // Rely on AOP infrastructure to tell us what interfaces to proxy.
        //根據(jù)AOP 框架來判斷需要代理的接口
        Class<?> targetClass = getTargetClass();
        
        if (targetClass == null) {
            throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
        }
        //設(shè)置代理對(duì)象的接口
        setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
    }
    // Initialize the shared singleton instance.
    super.setFrozen(this.freezeProxy);
    //getProxy()方法,通過createAopProxy() 方法返回的AopProxy 得到代理對(duì)象。
    this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;

}
/**

  • getProxy() 方法出現(xiàn)了AopProxy 接口對(duì)象。
    */
    protected Object getProxy(AopProxy aopProxy) {
    return aopProxy.getProxy(this.proxyClassLoader);
    }
    上面代碼中 createAopProxy() 返回的是一個(gè)AopProxy對(duì)象,這個(gè)對(duì)象有兩個(gè)實(shí)現(xiàn)類:JdkDynamicAopProxy,CglibAopProxy,看到名字就很清楚了分別對(duì)應(yīng)生成代理類不同的實(shí)現(xiàn)方式。getProxy() 方法調(diào)用AopProxy 類的getProxy() 方法返回代理對(duì)象。
    Spring 使用AopProxy 接口對(duì)象把AOP代理的實(shí)現(xiàn)和框架其它部分區(qū)分開,體現(xiàn)面向接口編程。

createAopProxy() 方法是在ProxyFactoryBean 父類 ProxyCreatorSupport 中實(shí)現(xiàn)的,ProxyCreatorSupport 中又調(diào)用了AopProxyFactory 默認(rèn)實(shí)現(xiàn) DefaultAopProxyFactory.createAopProxy() 方法生成AopProxy 代理對(duì)象。

/**

  • Subclasses should call this to get a new AOP proxy. They should <b>not</b>
  • create an AOP proxy with {@code this} as an argument.

子類調(diào)用這個(gè)方法生成 AOP proxy。

在 AdvisedProxy 子類 ProxyFactoryBean 中通過 AopProxyFactory 來生成代理類,AdvisedProxy 封裝了所有的生成代理對(duì)象信息,如:實(shí)現(xiàn)接口,目錄類等。
AopProxyFactory 使用的是 DefaultAopProxyFactory,這個(gè)對(duì)象在 ProxyFactoryBean 父類 ProxyCreatorSupport 中被創(chuàng)建。
createAopProxy() 方法參數(shù)就是 AdvisedProxy 類型,這里傳的是this,就是 ProxyFactoryBean,ProxyFactoryBean也是AdvisedProxy子類(可以查看上面的類關(guān)系圖)。

*/
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

//這里是調(diào)用 AopProxyFactory 默認(rèn)實(shí)現(xiàn) DefaultAopProxyFactory.createAopProxy() 方法生成AopProxy 代理對(duì)象。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

    //目錄對(duì)象的class
    Class<?> targetClass = config.getTargetClass();
    
    //沒有目標(biāo)對(duì)象拋出異常
    if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: " +
                "Either an interface or a target is required for proxy creation.");
    }
    //targetClass 是接口類,使用 JDK來生成 Proxy
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
        return new JdkDynamicAopProxy(config);
    }
    //如果不是接口類,使用CGLIB 生成代理對(duì)象
    return new ObjenesisCglibAopProxy(config);
}
else {
    return new JdkDynamicAopProxy(config);
}

}
JdkDynamicAopProxy 源碼分析:

JdkDynamicAopProxy 本身實(shí)現(xiàn)了 InvocationHandler 接口和 AopProxy 接口所以 JdkDynamicAopProxy實(shí)現(xiàn)的InvocationHandler.invoker() 方法就是Proxy 對(duì)象回調(diào)的方法。
實(shí)現(xiàn)的AopProxy.getProxy() 方法就是通過JDK動(dòng)態(tài)代理生成的代理對(duì)象,傳遞的InvocationHandler 對(duì)象就是 JdkDynamicAopProxy 自身。
這就是動(dòng)態(tài)代理了,切面的實(shí)惠就是在 invoke() 方法中體現(xiàn)的。后面再分析如何實(shí)現(xiàn)AOP。

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//獲取目標(biāo)類上的接口并且判斷是否需要添加SpringProxy Advised DecoratingProxy(spring4.3 新增) 接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

//判斷的目標(biāo)對(duì)象實(shí)現(xiàn)的接口是否定義了equals或hashCode方法,
//在invoke() 方法調(diào)用的時(shí)候會(huì)對(duì) equals 和 equals 做特殊的處理,參考后面
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

//返回動(dòng)態(tài)代理對(duì)象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

}
總結(jié):
通過AopProxy 對(duì)象封裝target 目標(biāo)對(duì)象之后,ProxyFactoryBean方法得到的對(duì)象已經(jīng)是一個(gè)AopProxy代理對(duì)象了,在ProxyFactoryBean 中配置的target目標(biāo)對(duì)象不會(huì)讓應(yīng)用直接調(diào)用其方法的實(shí)現(xiàn),對(duì)target目標(biāo)對(duì)象的方法調(diào)用會(huì)被AopProxy代理對(duì)象攔截,對(duì)于不同的AopProxy代理對(duì)象生成方式,會(huì)使用不同的攔截回調(diào)入口。對(duì)于 JDK的AopProxy代理對(duì)象,使用的是InvocationHander的invoker 回調(diào)入口。對(duì)于CGLIB的AopProxy代理對(duì)象,使用的是設(shè)置好的callbak 回調(diào),在這里callback回調(diào)中,對(duì)于AOP的實(shí)現(xiàn)是通過DynamicAdvisedInterceptor 來完成的,DynamicAdvisedInterceptor 的回調(diào)入口是 intercept 方法(后面再分析CGLIB)。
這里只是AopProxy 代理對(duì)象的生成,通過這個(gè)過程把代理對(duì)象和攔截器待調(diào)用的部分都準(zhǔn)備好。下面就分析AOP運(yùn)行過程中對(duì)這些攔截器和代理對(duì)象的調(diào)用過程。

AOP 攔截器調(diào)用實(shí)現(xiàn):

如果是JDK實(shí)現(xiàn)的代理對(duì)象就會(huì)通過InvocationHandler 來完成攔截器回調(diào),如果是CGLIB 就通過DynamicAdvisedInterceptor 來完成回調(diào)。
JdkDynamicAopProxy 的 invoke 攔截:
在 JdkDynamicAopProxy.getProxy() 方法中,調(diào)用的的JDK動(dòng)態(tài)代理生成代理類,JdkDynamicAopProxy 自身實(shí)現(xiàn)了InvocationHandler 接口,那么代理對(duì)象調(diào)用目標(biāo)對(duì)象方法時(shí)會(huì)被invoke() 方法攔截

JdkDynamicAopProxy.invoke() 源碼:

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

//從advised中獲取目標(biāo)對(duì)象
TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
    if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
        // The target does not implement the equals(Object) method itself.
        //目標(biāo)對(duì)象沒有重寫Object 的equals() 方法
        return equals(args[0]);
    }
    else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
        // The target does not implement the hashCode() method itself.
        //目標(biāo)對(duì)象沒有重寫 Object的 hashCode() 方法
        return hashCode();
    }
    else if (method.getDeclaringClass() == DecoratingProxy.class) {
        // There is only getDecoratedClass() declared -> dispatch to proxy config.
        // 如果方法是在DecoratingProxy聲明的,
        // DecoratingProxy 只有g(shù)etDecoratedClass() 一個(gè)方法,所有在這里直接調(diào)用
        // 返回代理類的終極目標(biāo)類。
        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...
        //Spring AOP不會(huì)增強(qiáng)直接實(shí)現(xiàn)Advised接口的目標(biāo)對(duì)象。
        //這里直接通過反射調(diào)用。
        return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
    }

    //返回值
    Object retVal;

    //是否暴露代理對(duì)象,如果暴露意味著在線程內(nèi)共享代理對(duì)象,在線程內(nèi)可通過AopContext 獲取代理對(duì)象。就是通過ThreadLocal 實(shí)現(xiàn)的。
    if (this.advised.exposeProxy) {
        // Make invocation available if necessary.
        oldProxy = AopContext.setCurrentProxy(proxy);
        setProxyContext = true;
    }

    // Get as late as possible to minimize the time we "own" the target,
    // in case it comes from a pool.
    // 目標(biāo)對(duì)象
    target = targetSource.getTarget();
    // 目標(biāo)對(duì)象類
    Class<?> targetClass = (target != null ? target.getClass() : null);

    // Get the interception chain for this method.
    //獲取目標(biāo)方法的攔截器鏈
    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.
    // 檢查是否的攔截器,如果沒有那么就直接通過反射調(diào)用目標(biāo)方法,MethodInvocation就不用創(chuàng)建了
    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.
        //如果沒有攔截器,就不用創(chuàng)建 MethodInvocation,直接在目標(biāo)對(duì)象上反射調(diào)用方法
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    }
    else {
        // We need to create a method invocation...
        //創(chuàng)建一個(gè) ReflectiveMethodInvocation,這個(gè)類是實(shí)現(xiàn)AOP的功能的封裝
        invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // Proceed to the joinpoint through the interceptor chain.
        retVal = invocation.proceed();
    }

    // Massage return value if necessary.
    Class<?> returnType = method.getReturnType();
    // retVal不空 并且和目標(biāo)方法的返回類型一致,就返回。
    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);
    }
}

}
注:
invoke 方法中獲取調(diào)用攔截器鏈方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
這個(gè)方法把 PintcutAdvice 封裝成 MethodInterceptor。MethodInterceptor 有兩個(gè)實(shí)現(xiàn)類具體的為 MethodBeforeAdviceInterceptor 和 AfterReturningAdviceInterceptor
MethodInterceptor.invoke() 方法,將的 ReflectiveMethodInvocation.proceed() 中被調(diào)用,MethodInterceptor.invoke()方法的參數(shù)就是 MethodInvocation 類型,而 ReflectiveMethodInvocation 是 MethodInvocation 的子類,在invoke() 方法中又回調(diào)了 MethodInvocation.proceed()方法,這樣就又回調(diào)回去了,當(dāng) "this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1" 時(shí)也就是攔截器調(diào)用完了,就通過反射調(diào)用目標(biāo)方法。
ReflectiveMethodInvocation 和 MethodInterceptor 就是實(shí)現(xiàn)Spring AOP 的核心所在。具體查看MethodBeforeAdviceInterceptor 和 AfterReturningAdviceInterceptor 這個(gè)兩個(gè)實(shí)現(xiàn)源碼就

JdkDynamicAopProxy AOP功能,就是通過 ReflectiveMethodInvocation 類實(shí)現(xiàn)的

ReflectiveMethodInvocation.proceed() 源碼分析:

//這個(gè)方法是遞歸方法,當(dāng)所有攔截器都執(zhí)行完畢了,就通過反射調(diào)用目標(biāo)方法返回。
@Override
@Nullable
public Object proceed() throws Throwable {

//  We start with an index of -1 and increment early.
//使用 currentInterceptorIndex 記錄攔截器調(diào)用的下標(biāo),當(dāng)所有攔截器都調(diào)用完畢后,通過反射調(diào)用目標(biāo)方法。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    //反射調(diào)用目標(biāo)方法
    return invokeJoinpoint();
}

//從攔截器鏈中獲取一個(gè)攔截器,下標(biāo)是  ++this.currentInterceptorIndex
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.
    
    //動(dòng)態(tài)匹配
    InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            
    //如果方法和定義的切點(diǎn)匹配成功就執(zhí)行
    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.
    //執(zhí)行到這里就是一個(gè) MethodInterceptor , 則直接調(diào)用
    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}

}
在示例代碼中配置的是通知器,不是切面,如果配置的是切面就要走動(dòng)態(tài)匹配了(動(dòng)態(tài)匹配就是走jdk的正則匹配 MethodMatcher ,不擴(kuò)展了)。

總結(jié):每個(gè) MethodInterceptor 對(duì)應(yīng)的都有實(shí)現(xiàn)AfterReturningAdviceInterceptor, MethodBeforeAdviceInterceptor, ThrowsAdviceInterceptor。如 MethodBeforeAdviceInterceptor

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
    this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
    return mi.proceed();
}

則是調(diào)用完invoke() 方法后,就又調(diào)用了MethodInvocation.proceed() 方法,又回到了上一步方法中,這樣一直循環(huán)調(diào)用,直到所有的interceptor 調(diào)用完畢。

總結(jié):ProxyFactoryBean 通過jdk動(dòng)態(tài)代理機(jī)制生成代理對(duì)象,當(dāng)調(diào)用代理對(duì)象方法時(shí),會(huì)被invoke() 方法攔截。在invoke() 方法中又獲取了此方法的攔截器,通過對(duì)攔截器的調(diào)用實(shí)現(xiàn)了spring aop功能。CGLIB的實(shí)現(xiàn)只是生成代理對(duì)象的方式不同,這就讓攔截器的入口有了變化。攔截器的生成和調(diào)用機(jī)制是一樣的??吹诙?。

注:這里通過 initializeAdvisorChain(); 把a(bǔ)dvice 封裝成了advisor,又如何把a(bǔ)dvisor 封裝成具體的interceptor 呢? 看后續(xù)...
————————————————
版權(quán)聲明:本文為CSDN博主「Jamin_Ma」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/convict_eva/article/details/81084833

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容