解析动态代理jdk的Proxy与spring的CGlib(包括区别介绍)

yizhihongxing

解析动态代理jdk的Proxy与spring的CGlib

什么是动态代理

动态代理是一种代理模式,它的作用是通过创建一个代理类来代替原始类进行引用,可以使用 Java API 来生成动态代理类,这个过程不需要预先定义代理类的代码。

JDK动态代理

JDK动态代理是Java提供的一种代理方式,需要有接口来实现代理。在运行时,它会为一个或多个接口动态生成一个实现类,该类实现了这些接口的所有方法,并将方法调用转移到一个指定的调用处理程序上。

JDK动态代理示例:

public interface IUserDao {
    void save();
}

public class UserDaoImpl implements IUserDao {
    @Override
    public void save() {
        System.out.println("save user");
    }
}

public class ProxyFactory implements InvocationHandler {
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxy() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object result = method.invoke(target, args);
        System.out.println("after");
        return result;
    }
}

public class JDKDynamicProxyTest {

    public static void main(String[] args) {
        IUserDao userDao = new UserDaoImpl();
        ProxyFactory proxyFactory = new ProxyFactory(userDao);
        IUserDao proxy = (IUserDao) proxyFactory.getProxy();
        proxy.save();
    }
}

CGLib动态代理

CGLib(Code Generation Library)动态代理也是创建代理的一种方式,它是一个强大的、高性能的代码生成包,它能够在运行时动态生成字节码,从而创建一个动态代理对象。

CGLib动态代理示例:

public class User {
    private int id;

    public User(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void save() {
        System.out.println("save user");
    }
}

public class CGLibProxy implements MethodInterceptor {

    private Object target;

    public CGLibProxy(Object target) {
        this.target = target;
    }

    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("after");
        return result;
    }
}

public class CGLibDynamicProxyTest {

    public static void main(String[] args) {
        CGLibProxy cgLibProxy = new CGLibProxy(new User(1));
        User proxy = (User) cgLibProxy.getProxy();
        proxy.save();
    }
}

JDK动态代理与CGLib动态代理的区别

  1. 接口:JDK动态代理可以为接口动态创建代理类,而CGLib动态代理不需要接口,可以针对类创建代理。

  2. 代理对象:JDK动态代理只能代理实现了接口的类,而CGLib动态代理可以代理任意类。

  3. 性能:CGLib动态代理更加强大和高效,但是在创建代理对象的时候比JDK动态代理更耗费时间和空间。

  4. 调用方式:JDK动态代理是通过反射调用方法,而CGLib动态代理是通过内存调用方法。

综上所述,JDK动态代理和CGLib动态代理在实现方式上存在一些差异,应根据不同的场景来选择合适的代理方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解析动态代理jdk的Proxy与spring的CGlib(包括区别介绍) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Vue.js构建你的第一个包并在NPM上发布的方法步骤

    下面我会详细讲解Vue.js构建你的第一个包并在NPM上发布的方法步骤,包括以下几个步骤: 初始化项目并创建组件 配置打包、发布到NPM 1. 初始化项目并创建组件 首先,我们需要使用Vue CLI来初始化我们的项目。在终端中运行以下命令: vue create my-first-package 接着,我们需要创建一个名为MyComponent.vue的组件…

    other 2023年6月27日
    00
  • postman接口做关联测试的方法步骤

    Postman接口做关联测试的方法步骤攻略 Postman是一款常用的API开发和测试工具,它提供了丰富的功能来进行接口测试。在进行关联测试时,我们可以使用Postman的环境变量和脚本功能来实现接口之间的数据传递和关联。下面是使用Postman进行接口关联测试的详细步骤: 步骤一:创建环境变量 打开Postman,点击左上角的齿轮图标,选择\”Manage…

    other 2023年7月29日
    00
  • fcrackzip官网

    当然,我很乐意为您提供有关“fcrackzip官网”的完整攻略。以下是详细的步骤和两个示例: 1. 什么是fcrackzip? fcrackzip是一个用于破解加密的ZIP文件的命令行工具。它可以使用暴力破解或字典攻击的方式来破解ZIP文件的密码。 2. fcrackzip官网 fcrackzip的官方网站是http://oldhome.schmorp.de…

    other 2023年5月6日
    00
  • Windows Server 2019和Windows Server, Version 1909的区别是什么

    Windows Server 2019和Windows Server, Version 1909是微软公司发布的两个Windows Server产品,它们之间存在一些区别和特性。本文将详细讲解它们之间的区别和如何选择。 区别 产品版本 Windows Server 2019是微软公司发布的最新版本,它是Windows Server产品系列的第九个主要版本。而…

    other 2023年6月27日
    00
  • Java中LinkedList原理代码解析

    Java中LinkedList原理代码解析 介绍 Java中的LinkedList是一种双向链表数据结构,在实际开发中经常被使用。LinkedList实现了List和Deque接口,可以被用作列表或队列。本文将深入探究LinkedList的实现原理和相应的代码解析。 LinkedList实现原理 LinkedList的实现原理主要包括以下几点: 内部节点类 …

    other 2023年6月27日
    00
  • python 使用递归的方式实现语义图片分割功能

    Python 使用递归的方式实现语义图片分割功能攻略如下: 1. 确定算法思路 语义图片分割功能主要是将一张图片按照视觉语义分成不同的区域,常用的算法包括基于聚类的算法和基于图像分割的算法。其中,基于图像分割的算法又可分为阈值分割、区域分割和边缘分割三种。 本文使用的是基于区域分割的算法,该算法将图片看作是一个图像区域集合,然后通过递归的方式将大的区域划分成…

    other 2023年6月27日
    00
  • Win11右键菜单太大怎么办?Win11右键菜单大小调整方法

    以下是详细的Win11右键菜单大小调整方法完整攻略。 问题描述 在Win11系统中,当我们在桌面或文件资源管理器中右键点击时,弹出的右键菜单可能会显示得过大,这可能会影响我们使用电脑的效率和体验。那么,如何调整Win11右键菜单的大小呢? 方法一:使用“调整所有的菜单尺寸”选项 一种解决方法是通过Windows 11的“调整所有的菜单尺寸”选项来调整右键菜单…

    other 2023年6月27日
    00
  • Xcode中Info.plist字段详解

    下面是详细的讲解: Xcode中Info.plist字段详解 什么是Info.plist文件 Info.plist 是苹果开发者必须添加到其应用程序捆绑包中的一个文件。这个文件是应用程序的“属性清单”,列出了应用程序所需的所有信息。 Info.plist文件的常用字段 Info.plist 中常用的字段有很多,下面分别介绍一下其中比较常用的几个: CFBun…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部