一、JDK的动态代理类


Java代码 


1. public interface
2. boolean
3. }

 


Java代码 


1. public class ServiceImpl implements
2.   
3. public boolean
4. if ("A".equals(data)) {  
5. return true;  
6. else
7. return false;  
8.         }  
9.     }  
10.   
11. }

 


Java代码 



    1. import
    2. import
    3.   
    4. public class ServiceHandler implements
    5. private
    6.   
    7. public
    8. this.delegateObj = delegateObj;  
    9.     }  
    10.   
    11. public
    12. throws
    13. "Begin Transaction....");  
    14. boolean
    15. "End Transaction....");  
    16. return
    17.     }  
    18.   
    19. }


     


    Java代码 


    1. import
    2.   
    3. public class
    4. public static void
    5. new
    6.   
    7. new
    8.   
    9.         IService is = (IService) Proxy.newProxyInstance(si.getClass()  
    10.                 .getClassLoader(), si.getClass().getInterfaces(), sh);  
    11.   
    12. "A");  
    13.     }  
    14. }

     

    二、CGLIB的动态代理类


     

     
    Figure 1: CGLIB Library and ASM Bytecode Framework图一显示了和CGLIB包和一些框架和语言的关系图。需要注意的是一些框架例如Spring AOP和Hibernate,它们为了满足需要经常同时使用JDK的动态代理和CGLIB包。Hiberater使用JDK的动态代理实现一个专门为WebShere应用服务器的事务管理适配器;Spring AOP,如果不强制使用CGLIB包,默认情况是使用JDK的动态代理来代理接口。

     


    Java代码 



      1. public class
      2.   
      3. public
      4. "----------test()----------";  
      5.         System.out.println(message);  
      6. return
      7.     }  
      8. }


       


      Java代码 


      1. import
      2. import
      3. import
      4.   
      5. public class MyMethodInterceptor implements
      6.   
      7. public
      8. throws
      9. ">>>MethodInterceptor start...");  
      10.         Object result = methodProxy.invokeSuper(object, args);  
      11. ">>>MethodInterceptor ending...");  
      12. return "hahahh";  
      13.     }  
      14. }

       


      Java代码 



        1. import
        2.   
        3. public class
        4. public static void
        5. new
        6. new
        7. class);  
        8.         String res = proxyTarget.execute();  
        9.         System.out.println(res);  
        10.     }  
        11.   
        12. public
        13. new
        14.         enhancer.setSuperclass(targetClass);  
        15. new
        16. return
        17.     }  
        18. }


         

        CGLIB包的基本代码很少,当学起来有一定的困难,主要是缺少文档,这也是开源软件的一个不足之处。目前CGLIB的版本是(2.1.2),主要由一下部分组成:

        •   net.sf.cglib.core
        Low-level bytecode manipulation classes; Most of them are related to ASM. 
         •  
          net.sf.cglib.transform
        Classes for class file transformations at runtime or build time 
         •  
          net.sf.cglib.proxy
        Classes for proxy creation and method interceptions 
         •  
          net.sf.cglib.reflect
        Classes for a faster reflection and C#-style delegates 
         •  
          net.sf.cglib.util
        Collection sorting utilities
        • net.sf.cglib.beans
          JavaBean related utilities 大多时候,仅仅为了动态地创建代理,你仅需要使用到代理包中很少的一些API。

          正如我们先前所讨论的,CGLIB包是在ASM之上的一个高级别的层。对代理那些没有实现接口的类非常有用。本质上,它是通过动态的生成一个子类去覆盖所要代理类的不是final的方法,并设置好callback,则原有类的每个方法调用就会转变成调用用户定义的拦截方法(interceptors),这比JDK动态代理方法快多了。
        •  
          net.sf.cglib.proxy.MethodInterceptor能够满足任何的拦截(interception )需要,当对有些情况下可能过度。为了简化和提高性能,CGLIB包提供了一些专门的回调(callback)类型。例如:
        • net.sf.cglib.proxy.FixedValue 
          为提高性能,FixedValue回调对强制某一特别方法返回固定值是有用的。
        • net.sf.cglib.proxy.NoOp 
          NoOp回调把对方法调用直接委派到这个方法在父类中的实现。
        • net.sf.cglib.proxy.LazyLoader 
          当实际的对象需要延迟装载时,可以使用LazyLoader回调。一旦实际对象被装载,它将被每一个调用代理对象的方法使用。
        • net.sf.cglib.proxy.Dispatcher 
          Dispathcer回调和LazyLoader回调有相同的特点,不同的是,当代理方法被调用时,装载对象的方法也总要被调用。
        • net.sf.cglib.proxy.ProxyRefDispatcher 
          ProxyRefDispatcher回调和Dispatcher一样,不同的是,它可以把代理对象作为装载对象方法的一个参数传递。
        •  
          代理类的所以方法经常会用到回调(callback),当是你也可以使用net.sf.cglib.proxy.CallbackFilter 有选择的对一些方法使用回调(callback),这种考虑周详的控制特性在JDK的动态代理中是没有的。在JDK代理中,对java.lang.reflect.InvocationHandler方法的调用对代理类的所以方法都有效。
           
          Use a MethodInterceptor为了更好的使用代理,我们可以使用自己定义的MethodInterceptor类型回调(callback)来代替net.sf.cglib.proxy.NoOp回调。当对代理中所有方法的调用时,都会转向MethodInterceptor类型的拦截(intercept)方法,在拦截方法中再调用底层对象相应的方法。
           
           
          Use a CallbackFilter
           
           
          小结 GLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。 它底层使用字节码处理框架ASM。其原理是,生产一个要代理类的子类,子类覆盖要代理的类的所有不是final的方法。 它比使用java反射的JDK动态代理要快。通常情况下,你可以使用JDK的动态代理创建代理,当你要代理的类没有实现接口 或者为了更好的性能,CGLIB是一个好的选择。