jdk代理 cglib代理 使用理解

问题

  • 动态代理一定需要有代理对象吗?
  • 动态代理有什么使用姿势?
  • jdk代理怎么用?
  • cglib代理怎么用?

动态代理一定需要有代理对象吗?

  • 答案:no
  • 使用过jdk动态代理的小伙伴一定发现了,其实jdk生成动态代理使用的方法根本不涉及代理对象
  • 当然,像mybatis框架使用的时候,就是利用动态代理只需要有接口就够了,来完成dao实现类。

动态代理有什么使用姿势?

  • 可以根据接口生成对应的实现类,实现类的逻辑随便写。

jdk代理怎么用?

  • 英文文档
  • 中文文档
  • 如果需要看代理类的文件,加上
    System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true")
    

方式一:直接生成代理类对象

  • 最常用、最简单的使用方式
  • 具体使用:
    • 直接调用Proxy生成代理类实例的方法,传必要的参数即可
      public static Object newProxyInstance(ClassLoader loader,
                                            Class<?>[] interfaces,
                                            InvocationHandler h)
      
    • loader——类加载器
    • interfaces——代理类需要实现的接口
    • h——方法被调用的时候真正执行的是InvocationHandler实现类的invoke方法
    • 例子:
        Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                                new Class<?>[] { Foo.class },
                                                handler); 
      

方式二:先生成跟接口相关的代理类,然后再把真正的InvocationHandler实现类传给代理类生成代理类对象

  • 多了一个步骤、生成了接口的代理类
  • 如果真正运行的逻辑有多个,可以直接复用代理类
  • 具体使用:
    • 先生成代理类,再根据代理类传一个InvocationHandler实现类,生成代理对象
      //生成代理类
      public static Class<?> getProxyClass(ClassLoader loader,
                                               Class<?>... interfaces)
      //获取代理类的构造方法,并实例化
      proxyClass.getConstructor(InvocationHandler.class).
                           newInstance(handler); 
                                     
      
    • 例子:
      InvocationHandler handler = new MyInvocationHandler(...);
      Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
      Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
                      newInstance(handler); 
      

cglib代理怎么用?

  • cglib api 英文
  • 这里推荐一篇文章,写得非常棒,暂时找不到了,找到了再补上
  • 如果需要查看class文件,加上
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:/class"); 
    
  • cglib动态代理的用法可太多了(有空再补)
  • 这里介绍一个常用的方式
    Child child = new Child();
    
    Enhancer enhancer = new Enhancer();
    
    enhancer.setSuperclass(Child.class);
    enhancer.setCallback(new EnhancedLogic());
    
    Child proxyChild = (Child) enhancer.create();
    proxyChild.cry();
    
posted @ 2020-11-20 22:00  躲在墙角的  阅读(61)  评论(0编辑  收藏  举报