zoukankan      html  css  js  c++  java
  • CGLib动态代理原理及实现

    JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

       简单的实现举例:

    这是一个需要被代理的类,也就是父类,通过字节码技术创建这个类的子类,实现动态代理。

    [java] view plain copy
     
    1. public class SayHello {  
    2.  public void say(){  
    3.   System.out.println("hello everyone");  
    4.  }  
    5. }  

    该类实现了创建子类的方法与代理的方法。getProxy(SuperClass.class)方法通过入参即父类的字节码,通过扩展父类的class来创建代理对象。intercept()方法拦截所有目标类方法的调用,obj表示目标类的实例,method为目标类方法的反射对象,args为方法的动态入参,proxy为代理类实例。proxy.invokeSuper(obj, args)通过代理类调用父类中的方法。

    [java] view plain copy
     
    1. public class CglibProxy implements MethodInterceptor{  
    2.  private Enhancer enhancer = new Enhancer();  
    3.  public Object getProxy(Class clazz){  
    4.   //设置需要创建子类的类  
    5.   enhancer.setSuperclass(clazz);  
    6.   enhancer.setCallback(this);  
    7.   //通过字节码技术动态创建子类实例  
    8.   return enhancer.create();  
    9.  }  
    10.  //实现MethodInterceptor接口方法  
    11.  public Object intercept(Object obj, Method method, Object[] args,  
    12.    MethodProxy proxy) throws Throwable {  
    13.   System.out.println("前置代理");  
    14.   //通过代理类调用父类中的方法  
    15.   Object result = proxy.invokeSuper(obj, args);  
    16.   System.out.println("后置代理");  
    17.   return result;  
    18.  }  
    19. }  

    具体实现类:

    [java] view plain copy
     
    1. public class DoCGLib {  
    2.  public static void main(String[] args) {  
    3.   CglibProxy proxy = new CglibProxy();  
    4.   //通过生成子类的方式创建代理类  
    5.   SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);  
    6.   proxyImp.say();  
    7.  }  
    8. }  

    输出结果:

    [plain] view plain copy
     
    1. 前置代理  
    2. hello everyone  
    3. 后置代理  

        CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/joyous-day/p/7010928.html
Copyright © 2011-2022 走看看