zoukankan      html  css  js  c++  java
  • 学习CGLIB与JDK动态代理的区别

    • 动态代理

    • 代理模式是Java中常见的一种模式。代理又分为静态代理和动态代理。静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进行包装,多个代理类存在重复代码,因此可以定义这样一个代理类,它能代理所有实现类的方法调用:根据传进来的实现类和方法名进行具体调用。——这就是动态代理。
    • JDK动态代理

    • 先上代码,一个接口类
    • 1 package com.example.demo;
      2 
      3 public interface IWrite {
      4     //
      5     void write();
      6 }
      IWrite
    • 一个实现类
      1 package com.example.demo;
      2 
      3 public class Author implements IWrite {
      4     @Override
      5     public void write() {
      6         System.out.println("writing");
      7     }
      8 }
    • 最后是代理类
      package com.example.demo;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      public class AuthorProxy implements InvocationHandler {
      
          private Object target;
      
          public Object bind(Object target) {
              this.target = target;  //接收业务实现类对象参数
      
              //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
              //创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
              return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),
                      this.target.getClass().getInterfaces(),this); }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("before");
              method.invoke(target,args);
              System.out.println("after");
              return null;
          }
      
          public static void main(String args[]) {
              Author write = new Author();
              AuthorProxy authorProxy = new AuthorProxy();
              IWrite author = (IWrite) authorProxy.bind(write);
      
              author.write();
      
          }
      }
    • jdk动态代理:代理所有“实现的有接口”的目标类。使用内置的Proxy实现动态代理有一个问题:被代理的类必须实现接口,未实现接口则没办法完成动态代理。
    • CGLib动态代理

    • 还是先上代码,一个不继承接口的业务类
      package com.example.demo;
      
      public class AuthorNoImplements {
          public void write() {
              System.out.println("writing...");
          }
      }
    • 最后是代理实现与测试
      package com.example.demo;
      
      import net.sf.cglib.proxy.Enhancer;
      import net.sf.cglib.proxy.MethodInterceptor;
      import net.sf.cglib.proxy.MethodProxy;
      
      import java.lang.reflect.Method;
      
      public class CglibProxy implements MethodInterceptor {
      
          private Object target;
      
          // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
          public Object bind(Object target) {
              this.target = target;
              Enhancer enhancer = new Enhancer();
              enhancer.setSuperclass(this.target.getClass());
              enhancer.setCallback(this);
              return enhancer.create();
          }
          @Override
          public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
              System.out.println("before");
              Object  obj = method.invoke(target, objects);
              System.out.println("after");
              return obj;
          }
          
          public static void main(String args[]) {
              CglibProxy cglibProxy = new CglibProxy();
              AuthorNoImplements authorNoImplements = (AuthorNoImplements) cglibProxy.bind(new AuthorNoImplements());
              authorNoImplements.write();
          }
      }
    • CGlib动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理;

    • CGLib 与JDK动态代理的区别

    • 最后说一下二者的区别:
    •  JDK代理是不需要以来第三方的库,只要要JDK环境就可以进行代理,它有几个要求
      * 实现InvocationHandler 
      * 使用Proxy.newProxyInstance产生代理对象
      * 被代理的对象必须要实现接口
    • CGLib 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承但是针对接口编程的环境下推荐使用JDK的代理。
  • 相关阅读:
    BeautifulSoup的基本用法
    [leedcode 189] Rotate Array
    [leedcode 187] Repeated DNA Sequences
    [leedcode 179] Largest Number
    [leedcode 174] Dungeon Game
    [leedcode 173] Binary Search Tree Iterator
    [leedcode 172] Factorial Trailing Zeroes
    [leedcode 171] Excel Sheet Column Number
    [leedcode 169] Majority Element
    [leedcode 168] Excel Sheet Column Title
  • 原文地址:https://www.cnblogs.com/aixinge/p/9046836.html
Copyright © 2011-2022 走看看