隨筆 - 2  文章 - 2  trackbacks - 0
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          留言簿

          隨筆檔案(1)

          文章分類(16)

          最新隨筆

          搜索

          •  

          最新評論

          java dynamic proxy

          核心java.lang.reflect.Proxy類

          // 根據給定接口和ClassLoader獲取Class對象
          // 使用Class.forName動態加載Class
          public static Class<?> getProxyClass(ClassLoader loader, Class<?> interfaces);
          // 創建代理對象
          // 通過反射的Constructor創建代理對象
          public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
          // 判斷是否是代理Class
          public static boolean isProxyClass(Class<?> cl);
          // 獲得代理對象的InvocationHandler
          public static InvocationHandler getInvocationHandler(Object proxy)

          java.lang.reflect.InvocationHandler接口

          // 反射調用代理類方法
          public Object invoke(Object proxy, Method method, Object[] args)
              
          throws Throwable;

          org.springframework.aop.framework.JdkDynamicAopProxy
          springframeworkAOP特性實現的基礎之一,通過動態代理實現
            1 package org.springframework.aop.framework;
            2 
            3 final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
            4 
            5     /** 代理的配置信息 */
            6     private final AdvisedSupport advised;
            7 
            8     public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
            9         Assert.notNull(config, "AdvisedSupport must not be null");
           10         if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
           11             throw new AopConfigException("No advisors and no TargetSource specified");
           12         }
           13         this.advised = config;
           14     }
           15 
           16 
           17     public Object getProxy() {
           18         return getProxy(ClassUtils.getDefaultClassLoader());
           19     }
           20     
           21     // 獲取代理對象
           22     public Object getProxy(ClassLoader classLoader) {
           23         if (logger.isDebugEnabled()) {
           24             logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
           25         }
           26         Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
           27         findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
           28         // 使用了Proxy動態代理創建代理對象
           29         return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
           30     }
           31 
           32 
           33     // 回調代理對象
           34     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           35         MethodInvocation invocation;
           36         Object oldProxy = null;
           37         boolean setProxyContext = false;
           38 
           39         TargetSource targetSource = this.advised.targetSource;
           40         Class targetClass = null;
           41         Object target = null;
           42 
           43         try {
           44             if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
           45                 // The target does not implement the equals(Object) method itself.
           46                 return equals(args[0]);
           47             }
           48             if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
           49                 // The target does not implement the hashCode() method itself.
           50                 return hashCode();
           51             }
           52             if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
           53                     method.getDeclaringClass().isAssignableFrom(Advised.class)) {
           54                 // Service invocations on ProxyConfig with the proxy config
           55                 return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
           56             }
           57 
           58             Object retVal;
           59 
           60             if (this.advised.exposeProxy) {
           61                 // Make invocation available if necessary.
           62                 oldProxy = AopContext.setCurrentProxy(proxy);
           63                 setProxyContext = true;
           64             }
           65 
           66             // May be null. Get as late as possible to minimize the time we "own" the target,
           67             // in case it comes from a pool.
           68             target = targetSource.getTarget();
           69             if (target != null) {
           70                 targetClass = target.getClass();
           71             }
           72 
           73             // Get the interception chain for this method.
           74             List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
           75 
           76             if (chain.isEmpty()) {
           77                 // 如果攔截鏈是空的,直接通過反射調用target對象的方法
           78                 // method.invoke(target, args);
           79                 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
           80             }else {
           81                 // 如果攔截鏈不為空,包裝一個反射方法調用
           82                 // 先調用織入的攔截器,最后仍然是反射調用target對象的方法
           83                 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
           84                 // Proceed to the joinpoint through the interceptor chain.
           85                 retVal = invocation.proceed();
           86             }
           87 
           88             // Massage return value if necessary.
           89             if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
           90                     !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
           91                 // Special case: it returned "this" and the return type of the method
           92                 // is type-compatible. Note that we can't help if the target sets
           93                 // a reference to itself in another returned object.
           94                 retVal = proxy;
           95             }
           96             return retVal;
           97         }
           98         finally {
           99             if (target != null && !targetSource.isStatic()) {
          100                 // Must have come from TargetSource.
          101                 targetSource.releaseTarget(target);
          102             }
          103             if (setProxyContext) {
          104                 // Restore old proxy.
          105                 AopContext.setCurrentProxy(oldProxy);
          106             }
          107         }
          108     }
          109 }
          110 



          posted on 2011-04-06 10:58 liucs 閱讀(1313) 評論(0)  編輯  收藏 所屬分類: Java

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 垣曲县| 大埔县| 神农架林区| 黑龙江省| 巴彦淖尔市| 清涧县| 晋州市| 四子王旗| 花莲县| 高阳县| 文安县| 鸡东县| 介休市| 化隆| 伊春市| 韩城市| 永川市| 普格县| 西峡县| 大石桥市| 灌南县| 兴城市| 安塞县| 南陵县| 孝义市| 雷州市| 枣强县| 老河口市| 大连市| 红安县| 玉溪市| 芷江| 南城县| 衡山县| 丹江口市| 当雄县| 永靖县| 霍州市| 江华| 高尔夫| 滦南县|