Java JDK 和 CGLib 动态代理怎么实现

首页 / 常见问题 / 低代码开发 / Java JDK 和 CGLib 动态代理怎么实现
作者:开发工具 发布时间:12-10 09:34 浏览量:5628
logo
织信企业级低代码开发平台
提供表单、流程、仪表盘、API等功能,非IT用户可通过设计表单来收集数据,设计流程来进行业务协作,使用仪表盘来进行数据分析与展示,IT用户可通过API集成第三方系统平台数据。
免费试用

Java JDK动态代理和CGLib动态代理都可以实现在运行时动态创建代理对象,从而在不修改源码的情况下增强或控制对目标对象的访问。JDK动态代理通过反射机制实现、它要求目标对象必须实现接口、而CGLib动态代理则通过继承目标类的方式实现,通常用于无法实现接口的类。接下来,我们将详细探讨如何实现JDK和CGLib动态代理。

一、JDK动态代理的实现

JDK动态代理是基于接口实现的,它使用java.lang.reflect.Proxy类来创建代理对象,并且通过实现InvocationHandler接口自定义方法在调用处理器中处理方法调用。

创建InvocationHandler实现类

首先,定义一个InvocationHandler接口的实现类,此类会重写invoke方法,以定义在方法调用时所执行的代理逻辑。

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

// 目标对象,通过反射来调用目标方法

private Object target;

public MyInvocationHandler(Object target) {

this.target = target;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// 在调用具体方法前可以添加自定义操作

System.out.println("Before method call");

// 通过反射调用目标对象的方法

Object result = method.invoke(target, args);

// 在调用具体方法后可以添加自定义操作

System.out.println("After method call");

return result;

}

}

使用Proxy创建代理对象

通过Proxy.newProxyInstance方法创建一个实现了目标接口的代理对象。

import java.lang.reflect.Proxy;

public class ProxyFactory {

public static Object getProxy(Object target) {

return Proxy.newProxyInstance(

target.getClass().getClassLoader(), // 目标类的类加载器

target.getClass().getInterfaces(), // 目标类实现的接口

new MyInvocationHandler(target) // InvocationHandler实现类

);

}

}

二、CGLib动态代理的实现

CGLib通过继承目标类在运行时生成的子类来实现,它依赖于net.sf.cglib.proxy.Enhancer类和MethodInterceptor接口。

创建MethodInterceptor实现类

首先,定义一个MethodInterceptor接口的实现类,类似InvocationHandler,这个类也需要重写一个方法,不同的是这里重写的是intercept方法。

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

public class MyMethodInterceptor implements MethodInterceptor {

// 实现MethodInterceptor接口的intercept方法,定义代理逻辑

@Override

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

// 在调用方法前可以执行某些操作

System.out.println("Before method call");

// 调用代理对象父类的方法(即目标类的方法)

Object result = proxy.invokeSuper(obj, args);

// 在调用方法后可以执行某些操作

System.out.println("After method call");

return result;

}

}

使用Enhancer创建代理对象

使用Enhancer类生成代理对象,Enhancer是CGLib提供的一个类生成类。

import net.sf.cglib.proxy.Enhancer;

public class CglibProxyFactory {

public static Object getProxy(Class<?> clazz) {

// 创建Enhancer对象

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(clazz); // 设置需要代理的类

enhancer.setCallback(new MyMethodInterceptor()); // 设置MethodInterceptor实现类

return enhancer.create(); // 创建代理对象

}

}

通过上面的步骤,我们可以生成任意类的子类并在运行时通过拦截器对方法调用进行控制。这两种动态代理的底层实现机制不同,但都达到了在不修改源码的前提下增强类的行为的目的。实际应用中,这两种代理有各自的使用场景,JDK动态代理由于只能针对实现了接口的类,因此使用面相对窄;而CGLib动态代理没有这个限制,但由于使用了继承,因此不能对final类以及final方法进行代理。

相关问答FAQs:

问题1: Java的JDK动态代理和CGLib动态代理分别是如何实现的?
答:Java的JDK动态代理是通过反射机制来实现的,它要求被代理的目标类必须实现一个接口,代理类在运行时动态生成,在调用代理方法时会通过反射调用目标类的方法。而CGLib动态代理则是通过继承目标类来实现的,代理类是目标类的子类,在调用代理方法时直接调用子类的方法,因此不要求目标类实现接口。

问题2: JDK动态代理和CGLib动态代理在使用场景上有什么区别?
答:JDK动态代理适用于基于接口的代理,它要求被代理的目标类实现一个接口,在运行时生成代理对象。而CGLib动态代理适用于对类进行代理,它直接继承目标类并生成代理对象。因此,如果目标类已经实现了接口,我们可以使用JDK动态代理;如果目标类没有实现接口或者我们想要代理类的所有方法,我们可以使用CGLib动态代理。

问题3: JDK动态代理和CGLib动态代理在性能上有什么区别?
答:JDK动态代理在生成代理对象时,需要通过反射调用目标类的方法,这个过程相对较慢,适用于对性能要求不高的场景。而CGLib动态代理通过继承目标类,直接调用子类的方法,省去了反射的过程,因此性能比JDK动态代理更高。但是CGLib生成的代理类需要动态加载到JVM中,所以在启动时会稍微慢一些。因此,在性能要求较高的场景下,可以考虑使用CGLib动态代理。

最后建议,企业在引入信息化系统初期,切记要合理有效地运用好工具,这样一来不仅可以让公司业务高效地运行,还能最大程度保证团队目标的达成。同时还能大幅缩短系统开发和部署的时间成本。特别是有特定需求功能需要定制化的企业,可以采用我们公司自研的企业级低代码平台织信Informat。 织信平台基于数据模型优先的设计理念,提供大量标准化的组件,内置AI助手、组件设计器、自动化(图形化编程)、脚本、工作流引擎(BPMN2.0)、自定义API、表单设计器、权限、仪表盘等功能,能帮助企业构建高度复杂核心的数字化系统。如ERP、MES、CRM、PLM、SCM、WMS、项目管理、流程管理等多个应用场景,全面助力企业落地国产化/信息化/数字化转型战略目标。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系邮箱:hopper@cornerstone365.cn 处理,核实后本网站将在24小时内删除。

最近更新

什么软件研发公司好用一点
12-17 18:14
软件研发公司有哪些
12-17 18:14
软件研发公司会计怎么做账
12-17 18:14
软件研发公司怎么做账
12-17 18:14
软件研发公司安全生产
12-17 18:14
精诚mes软件研发公司叫什么
12-17 18:14
mes软件研发公司叫什么
12-17 18:14
mes生产管理系统软件研发公司
12-17 18:14
制造业mes软件研发公司
12-17 18:14

立即开启你的数字化管理

用心为每一位用户提供专业的数字化解决方案及业务咨询

  • 深圳市基石协作科技有限公司
  • 地址:深圳市南山区科技中一路大族激光科技中心909室
  • 座机:400-185-5850
  • 手机:137-1379-6908
  • 邮箱:sales@cornerstone365.cn
  • 微信公众号二维码

© copyright 2019-2024. 织信INFORMAT 深圳市基石协作科技有限公司 版权所有 | 粤ICP备15078182号

前往Gitee仓库
微信公众号二维码
咨询织信数字化顾问获取最新资料
数字化咨询热线
400-185-5850
申请预约演示
立即与行业专家交流