欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Spring源代碼解析(七):Spring AOP中對攔截器調用的實(shí)現

前面我們分析了Spring AOP實(shí)現中得到Proxy對象的過(guò)程,下面我們看看在Spring AOP中攔截器鏈是怎樣被調用的,也就是Proxy模式是怎樣起作用的,或者說(shuō)Spring是怎樣為我們提供AOP功能的;
在JdkDynamicAopProxy中生成Proxy對象的時(shí)候:

Java代碼
  1. return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);  
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);


這里的this參數對應的是InvocationHandler對象,這里我們的JdkDynamicAopProxy實(shí)現了這個(gè)接口,也就是說(shuō)當Proxy對象的函數被調用的時(shí)候,這個(gè)InvocationHandler的invoke方法會(huì )被作為回調函數調用,下面我們看看這個(gè)方法的實(shí)現:

Java代碼
  1. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  2.     MethodInvocation invocation = null;   
  3.     Object oldProxy = null;   
  4.     boolean setProxyContext = false;   
  5.   
  6.     TargetSource targetSource = this.advised.targetSource;   
  7.     Class targetClass = null;   
  8.     Object target = null;   
  9.   
  10.     try {   
  11.         // Try special rules for equals() method and implementation of the   
  12.         // Advised AOP configuration interface.   
  13.   
  14.         if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {   
  15.             // What if equals throws exception!?   
  16.             // This class implements the equals(Object) method itself.   
  17.             return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;   
  18.         }   
  19.         if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {   
  20.             // This class implements the hashCode() method itself.   
  21.             return new Integer(hashCode());   
  22.         }   
  23.         if (Advised.class == method.getDeclaringClass()) {   
  24.             // service invocations on ProxyConfig with the proxy config   
  25.             return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);   
  26.         }   
  27.   
  28.         Object retVal = null;   
  29.   
  30.         if (this.advised.exposeProxy) {   
  31.             // make invocation available if necessary   
  32.             oldProxy = AopContext.setCurrentProxy(proxy);   
  33.             setProxyContext = true;   
  34.         }   
  35.   
  36.         // May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,   
  37.         // in case it comes from a pool.   
  38.         // 這里是得到目標對象的地方,當然這個(gè)目標對象可能來(lái)自于一個(gè)實(shí)例池或者是一個(gè)簡(jiǎn)單的JAVA對象   
  39.         target = targetSource.getTarget();   
  40.         if (target != null) {   
  41.             targetClass = target.getClass();   
  42.         }   
  43.   
  44.         // get the interception chain for this method   
  45.         // 這里獲得定義好的攔截器鏈   
  46.         List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(   
  47.                 this.advised, proxy, method, targetClass);   
  48.   
  49.         // Check whether we have any advice. If we don't, we can fallback on direct   
  50.         // reflective invocation of the target, and avoid creating a MethodInvocation.   
  51.         // 如果沒(méi)有設定攔截器,那么我們就直接調用目標的對應方法   
  52.         if (chain.isEmpty()) {   
  53.             // We can skip creating a MethodInvocation: just invoke the target directly   
  54.             // Note that the final invoker must be an InvokerInterceptor so we know it does   
  55.             // nothing but a reflective operation on the target, and no hot swapping or fancy proxying   
  56.             retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);   
  57.         }   
  58.         else {   
  59.             // We need to create a method invocation...   
  60.             // invocation = advised.getMethodInvocationFactory().getMethodInvocation(   
  61.             //         proxy, method, targetClass, target, args, chain, advised);   
  62.             // 如果有攔截器的設定,那么需要調用攔截器之后才調用目標對象的相應方法   
  63.             // 這里通過(guò)構造一個(gè)ReflectiveMethodInvocation來(lái)實(shí)現,下面我們會(huì )看這個(gè)ReflectiveMethodInvocation類(lèi)   
  64.             invocation = new ReflectiveMethodInvocation(   
  65.                     proxy, target, method, args, targetClass, chain);   
  66.   
  67.             // proceed to the joinpoint through the interceptor chain   
  68.             // 這里通過(guò)ReflectiveMethodInvocation來(lái)調用攔截器鏈和相應的目標方法   
  69.             retVal = invocation.proceed();   
  70.         }   
  71.   
  72.         // massage return value if necessary   
  73.         if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {   
  74.             // Special case: it returned "this" and the return type of the method is type-compatible   
  75.             // Note that we can't help if the target sets   
  76.             // a reference to itself in another returned object.   
  77.             retVal = proxy;   
  78.         }   
  79.         return retVal;   
  80.     }   
  81.     finally {   
  82.         if (target != null && !targetSource.isStatic()) {   
  83.             // must have come from TargetSource   
  84.             targetSource.releaseTarget(target);   
  85.         }   
  86.   
  87.         if (setProxyContext) {   
  88.             // restore old proxy   
  89.             AopContext.setCurrentProxy(oldProxy);   
  90.         }   
  91.     }   
  92. }  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MethodInvocation invocation = null;Object oldProxy = null;boolean setProxyContext = false;TargetSource targetSource = this.advised.targetSource;Class targetClass = null;Object target = null;try {// Try special rules for equals() method and implementation of the// Advised AOP configuration interface.if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {// What if equals throws exception!?// This class implements the equals(Object) method itself.return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;}if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {// This class implements the hashCode() method itself.return new Integer(hashCode());}if (Advised.class == method.getDeclaringClass()) {// service invocations on ProxyConfig with the proxy configreturn AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}Object retVal = null;if (this.advised.exposeProxy) {// make invocation available if necessaryoldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,// in case it comes from a pool.// 這里是得到目標對象的地方,當然這個(gè)目標對象可能來(lái)自于一個(gè)實(shí)例池或者是一個(gè)簡(jiǎn)單的JAVA對象target = targetSource.getTarget();if (target != null) {targetClass = target.getClass();}// get the interception chain for this method// 這里獲得定義好的攔截器鏈List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this.advised, proxy, 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.// 如果沒(méi)有設定攔截器,那么我們就直接調用目標的對應方法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 proxyingretVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);}else {// We need to create a method invocation...// invocation = advised.getMethodInvocationFactory().getMethodInvocation(//         proxy, method, targetClass, target, args, chain, advised);// 如果有攔截器的設定,那么需要調用攔截器之后才調用目標對象的相應方法// 這里通過(guò)構造一個(gè)ReflectiveMethodInvocation來(lái)實(shí)現,下面我們會(huì )看這個(gè)ReflectiveMethodInvocation類(lèi)invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// proceed to the joinpoint through the interceptor chain// 這里通過(guò)ReflectiveMethodInvocation來(lái)調用攔截器鏈和相應的目標方法retVal = invocation.proceed();}// massage return value if necessaryif (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {// 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;}return retVal;}finally {if (target != null && !targetSource.isStatic()) {// must have come from TargetSourcetargetSource.releaseTarget(target);}if (setProxyContext) {// restore old proxyAopContext.setCurrentProxy(oldProxy);}}}


我們先看看目標對象方法的調用,這里是通過(guò)AopUtils的方法調用 - 使用反射機制來(lái)對目標對象的方法進(jìn)行調用:

Java代碼
  1. public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)   
  2.     throws Throwable {   
  3.   
  4.     // Use reflection to invoke the method.   
  5.     // 利用放射機制得到相應的方法,并且調用invoke   
  6.     try {   
  7.         if (!Modifier.isPublic(method.getModifiers()) ||   
  8.                 !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {   
  9.             method.setAccessible(true);   
  10.         }   
  11.         return method.invoke(target, args);   
  12.     }   
  13.     catch (InvocationTargetException ex) {   
  14.         // Invoked method threw a checked exception.   
  15.         // We must rethrow it. The client won't see the interceptor.   
  16.         throw ex.getTargetException();   
  17.     }   
  18.     catch (IllegalArgumentException ex) {   
  19.         throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +   
  20.                 method + "] on target [" + target + "]", ex);   
  21.     }   
  22.     catch (IllegalAccessException ex) {   
  23.         throw new AopInvocationException("Couldn't access method: " + method, ex);   
  24.     }   
  25. }  
    public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)throws Throwable {// Use reflection to invoke the method.// 利用放射機制得到相應的方法,并且調用invoketry {if (!Modifier.isPublic(method.getModifiers()) ||!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {method.setAccessible(true);}return method.invoke(target, args);}catch (InvocationTargetException ex) {// Invoked method threw a checked exception.// We must rethrow it. The client won't see the interceptor.throw ex.getTargetException();}catch (IllegalArgumentException ex) {throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +method + "] on target [" + target + "]", ex);}catch (IllegalAccessException ex) {throw new AopInvocationException("Couldn't access method: " + method, ex);}}


對攔截器鏈的調用處理是在ReflectiveMethodInvocation里實(shí)現的:

Java代碼
  1. public Object proceed() throws Throwable {   
  2.     //    We start with an index of -1 and increment early.   
  3.     // 這里直接調用目標對象的方法,沒(méi)有攔截器的調用或者攔截器已經(jīng)調用完了,這個(gè)currentInterceptorIndex的初始值是0   
  4.     if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {   
  5.         return invokeJoinpoint();   
  6.     }   
  7.   
  8.     Object interceptorOrInterceptionAdvice =   
  9.         this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex);   
  10.     if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {   
  11.         // Evaluate dynamic method matcher here: static part will already have   
  12.         // been evaluated and found to match.   
  13.         // 這里獲得相應的攔截器,如果攔截器可以匹配的上的話(huà),那就調用攔截器的invoke方法   
  14.         InterceptorAndDynamicMethodMatcher dm =   
  15.             (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;   
  16.         if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {   
  17.             return dm.interceptor.invoke(nextInvocation());   
  18.         }   
  19.         else {   
  20.             // Dynamic matching failed.   
  21.             // Skip this interceptor and invoke the next in the chain.   
  22.             // 如果攔截器匹配不上,那就調用下一個(gè)攔截器,這個(gè)時(shí)候攔截器鏈的位置指示后移并迭代調用當前的proceed方法   
  23.             this.currentInterceptorIndex++;   
  24.             return proceed();   
  25.         }   
  26.     }   
  27.     else {   
  28.         // It's an interceptor, so we just invoke it: The pointcut will have   
  29.         // been evaluated statically before this object was constructed.   
  30.         return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation());   
  31.     }   
  32. }  
    public Object proceed() throws Throwable {//    We start with an index of -1 and increment early.// 這里直接調用目標對象的方法,沒(méi)有攔截器的調用或者攔截器已經(jīng)調用完了,這個(gè)currentInterceptorIndex的初始值是0if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {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.// 這里獲得相應的攔截器,如果攔截器可以匹配的上的話(huà),那就調用攔截器的invoke方法InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {return dm.interceptor.invoke(nextInvocation());}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in the chain.// 如果攔截器匹配不上,那就調用下一個(gè)攔截器,這個(gè)時(shí)候攔截器鏈的位置指示后移并迭代調用當前的proceed方法this.currentInterceptorIndex++;return proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation());}}


這里把當前的攔截器鏈以及在攔截器鏈的位置標志都clone到一個(gè)MethodInvocation對象了,作用是當前的攔截器執行完之后,會(huì )繼續沿著(zhù)得到這個(gè)攔截器鏈執行下面的攔截行為,也就是會(huì )迭代的調用上面這個(gè)proceed:

Java代碼
  1. private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {   
  2.     ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();   
  3.     invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1;   
  4.     invocation.parent = this;   
  5.     return invocation;   
  6. }  
    private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1;invocation.parent = this;return invocation;}


這里的nextInvocation就已經(jīng)包含了當前的攔截鏈的基本信息,我們看到在Interceptor中的實(shí)現比如TransactionInterceptor的實(shí)現中:

Java代碼
  1. public Object invoke(final MethodInvocation invocation) throws Throwable {   
  2.    ......//這里是TransactionInterceptor插入的事務(wù)處理代碼,我們會(huì )在后面分析事務(wù)處理實(shí)現的時(shí)候進(jìn)行分析   
  3.         try {   
  4.             //這里是對配置的攔截器鏈進(jìn)行迭代處理的調用   
  5.             retVal = invocation.proceed();   
  6.         }   
  7.    ......//省略了和事務(wù)處理的異常處理代碼 ,也是TransactionInterceptor插入的處理   
  8.       else {   
  9.         try {   
  10.             Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,   
  11.                     new TransactionCallback() {   
  12.                         public Object doInTransaction(TransactionStatus status) {   
  13.                              //這里是TransactionInterceptor插入對事務(wù)處理的代碼   
  14.                             TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);   
  15.                             //這里是對配置的攔截器鏈進(jìn)行迭代處理的調用,接著(zhù)順著(zhù)攔截器進(jìn)行處理   
  16.                             try {                           
  17.                                 return invocation.proceed();   
  18.                             }   
  19.    ......//省略了和事務(wù)處理的異常處理代碼 ,也是TransactionInterceptor插入的處理   
  20.    }  
    public Object invoke(final MethodInvocation invocation) throws Throwable {......//這里是TransactionInterceptor插入的事務(wù)處理代碼,我們會(huì )在后面分析事務(wù)處理實(shí)現的時(shí)候進(jìn)行分析try {//這里是對配置的攔截器鏈進(jìn)行迭代處理的調用retVal = invocation.proceed();}......//省略了和事務(wù)處理的異常處理代碼 ,也是TransactionInterceptor插入的處理else {try {Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,new TransactionCallback() {public Object doInTransaction(TransactionStatus status) {//這里是TransactionInterceptor插入對事務(wù)處理的代碼TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);//這里是對配置的攔截器鏈進(jìn)行迭代處理的調用,接著(zhù)順著(zhù)攔截器進(jìn)行處理try {return invocation.proceed();}......//省略了和事務(wù)處理的異常處理代碼 ,也是TransactionInterceptor插入的處理}


從上面的分析我們看到了Spring AOP的基本實(shí)現,比如Spring怎樣得到Proxy,怎樣利用JAVA Proxy以及反射機制對用戶(hù)定義的攔截器鏈進(jìn)行處理。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
filter 練習代碼 敏感字
Jdk動(dòng)態(tài)代理原理解析
細說(shuō)JDK動(dòng)態(tài)代理的實(shí)現原理
webwork攔截器interceptor 之 ActionInvocation 意義
深入淺出Mybatis
java SE靜態(tài)代理和動(dòng)態(tài)代理
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久