• 动态代理

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

  • 先上代码,一个接口类
  •  package com.example.demo;
    
     public interface IWrite {
    //写
    void write();
    }

    IWrite

  • 一个实现类
     package com.example.demo;
    
     public class Author implements IWrite {
    @Override
    public void write() {
    System.out.println("writing");
    }
    }
  • 最后是代理类
    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的代理。

学习CGLIB与JDK动态代理的区别的更多相关文章

  1. Cglib 与 JDK动态代理

    作者:xiaolyuh 时间:2019/09/20 09:58 AOP 代理的两种实现: jdk是代理接口,私有方法必然不会存在在接口里,所以就不会被拦截到: cglib是子类,private的方法照 ...

  2. Cglib 与 JDK动态代理的运行性能比较

    都说 Cglib 创建的动态代理的运行性能比 JDK 动态代理能高出大概 10 倍,今日抱着怀疑精神验证了一下,发现情况有所不同,遂贴出实验结果,以供参考和讨论. 代码很简单,首先,定义一个 Test ...

  3. 面试造火箭系列,栽在了cglib和jdk动态代理

    "喂,你好,我是XX巴巴公司的技术面试官,请问你是张小帅吗".声音是从电话那头传来的 "是的,你好".小帅暗喜,大厂终于找上我了. "下面我们来进行一 ...

  4. 输出cglib以及jdk动态代理产生的class文件

      --该设置用于输出jdk动态代理产生的类 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles&q ...

  5. CGlib和JDK动态代理

    一.CGlib动态代理     JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的1:字节码技术,其原理是通过字节 ...

  6. spring cglib 与 jdk 动态代理

    1. 概述 JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理 Cglib动态代理是 利用asm开源包 把被代理类的clas ...

  7. CGLIB和Java动态代理的区别(笔记)

    java常用知识点: 1.Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承):CGLIB能够代理普通类:2.Jav ...

  8. 有点深度的聊聊JDK动态代理

    在接触SpringAOP的时候,大家一定会被这神奇的功能所折服,想知道其中的奥秘,底层到底是如何实现的.于是,大家会通过搜索引擎,知道了一个陌生的名词:动态代理,慢慢的又知道了动态代理有多种实现方式, ...

  9. spring源码学习【准备】之jdk动态代理和cglib动态代理的区别和性能

    一:区别:---->JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了.--->JDK的动态代理机制只能代理实现了接口的类,而不能 ...

随机推荐

  1. Android并发编程 多线程与锁

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的. 前言 前一篇Android并发编程开篇呢,主要是简单介绍一下线程以及 ...

  2. [51nod1514] 美妙的序列

    Description 如果对于一个 \(1\sim n\) 的排列满足: 在 \(1\sim n-1\) 这些位置之后将序列断开,使得总可以从右边找一个数,使得该数不会比左边所有数都大,则称该序列是 ...

  3. C 语言精髓之变参函数

    我们以 printf 这个 very 熟悉的函数为例,来分析一下变参函数.先看下 printf 函数的定义: int printf(const char *fmt, ...) { int i; int ...

  4. OOP 面向对象的理解

    概念 面向对象编程(OOP)是一种编程语言模型,围绕对象是行为.数据.逻辑. 从历史上看,程序被视为一种逻辑程序,它接收输入数据,处理数据并生成输出数据. 基础 面向对象的3大核心思想:封装.继承.多 ...

  5. T-SQL:谓词和运算符(六)

    谓词一般有 where和having,check  谓词只计算 TRUE ,FALSE或者UNKNOWN  逻辑表达式  如 AND 和OR 1.IN 谓词的用法 SELECT orderid, em ...

  6. jquery中innerwidth,outerwidth,outerwidth和width的区别

    在jQuery中,width()方法用于获得元素宽度: innerWidth()方法用于获得包括内边界(padding)的元素宽度, outerWidth()方法用于获得包括内边界(padding)和 ...

  7. PowerDesigner 修改Name ,Code 不变

    tools-> General   Options-> Dialog:Operation   Modes: 去掉 NameToCodeMirroring 前面的√      

  8. Java基础——Oracle(五)

    一.Oracle  中的分页 1) select * from emp; 2)select * ,rownum from emp; //这样写不行 3)select ename,job,sal,row ...

  9. Django Rest Framework之认证

    代码基本结构 url.py: from django.conf.urls import url, include from web.views.s1_api import TestView urlpa ...

  10. 【pygame游戏编程】第四篇-----打字测速游戏

    下面我们一起用pygame编写一个打字测速游戏 这是一个很实用的有趣的小游戏: 开始之前先来学习几个小函数: 1. ord(ch) python内置函数,传入一个字符,返回字符的ascii码 2.ch ...