JDK动态代理和CGLiB动态代理

  1. JDK动态代理java

    JDK动态代理要求类必须实现某一接口,代理类是同一接口的实现类。性能

    JDK动态代理主要涉及两个类:Proxy和InvocationHandler。InvocationHandler是一个接口,能够经过实现该接口定义横切逻辑,并经过反射机制调用目标类的代码,动态的将横切逻辑与业务逻辑交织在一块儿。Proxy利用InvocationHandler动态建立一个符合某一接口的实例,生成目标类的代理对象。this

    public class MyInvocationHandler implements InvocationHandler {
         private Object target;
        public MyInvocationHandler(Object target){
              this.target = target;
        }
        public Object invoke(Object proxy, Method method, Object[] args) {
              begin();
              Object obj = method.invoke(target, args);
              end();
              return obj;
         }
    }
         
    建立代理实例
    public class Test {
         public static void main(String [] args){
              Target target = new TargetImpl();
               MyInvocationHandler handler = new MyInvocationHandler(target);
               Target proxy = (Target) Proxy.newProxyInstance(
                       target.getClass().getClassLoader(),
                       target.getInterfaces(),
                       handler);
                proxy.test();
         }
    }
  2. CGLiB动态代理代理

    JDK动态代理有一个缺点,就是它只能为接口建立代理实例。对于没有经过接口实现业务逻辑的类,经过CGLiB来实现代理。code

    CGLiB采用很是底层的字节码技术,能够为一个类建立子类,并在子类中采用方法拦截的技术拦截全部父类方法的调用,并顺势织入横切逻辑。对象

    public class CglibProxy implements MethodInterceptor {
         private Enhancer enhancer = new Enhancer();
         public Object getProxy(Class clazz) {
              enhancer.setSuperclass(clazz);
              enhancer.setCallback(this);
              return enhancer.create();
         }
         public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
              begin();
              Object result = proxy.invokeSuper(obj, args);
             end();
             return result;
         }
    }
    
    建立动态代理
    public class Test {
         public static void main(String [] args) {
              CglibProxy proxy = new CglibProxy();
             TargetImpl target = (TargetImpl) proxy.getProxy(TargetImpl.class);
             target.test();
             
         }
    }

  3. 对比接口

    CGLiB所建立的动态代理对象要比JDK所建立的动态代理对象的性能要高出10倍,但CGLiB建立动态代理所花费的时间却比JDK动态代理多8倍。get

    对于singleton的代理对象或具备实例池的代理,由于无需频繁的建立代理对象,因此适合使用CGLiB代理,繁殖则使用JDK动态代理。io

    因为CGLIB动态代理采用动态建立子类的方式生成代理对象,因此不能对目标类中 的final方法进行代理class

相关文章
相关标签/搜索