
JAVA动态代理简单总结
定义目标类:实现需代理的接口。 创建 InvocationHandler:关联代理逻辑(如调用前后处理)。 调用 Proxy.newProxyInstance:生成代理对象。 属性逐步解析:
无需接口实现要求:"@-target"类不需要实现特定接口,可直接进行方法拦截。 继承增强:生成代理类继承目标类,非final方法可重写。 效率更高:基于类操作,性能优于反射实现。
发布日期:2025-04-02 01:28:18
浏览次数:11
分类:精选文章
本文共 3198 字,大约阅读时间需要 10 分钟。
JDK与CGILB动态代理实现对比
JDK和CGILB两种动态代理实现方式各有特点,了解其实现机制对于开发有重要意义。本文将从 InvocationHandler 与 Proxy(JDK实现)、MethodInterceptor 与 Enchancer(CGILB实现)两个方面进行对比分析。
JDK动态代理实现
InvocationHandler 与 Proxy
JDK动态代理的核心组件包括 InvocationHandler 和 Proxy。
Proxy 组件
Proxy 是动态代理的核心实现类,主要负责根据指定接口生成动态代理类。 Proxy 类提供了两个重要方法:
Proxy.newProxyInstance:用于根据指定的接口生成动态代理对象。
- 参数解析:
loader
:类加载器,负责生成代理类所需的类加载。interfaces
:接口数组,指定需要代理接口。handler
:InvocationHandler 实例,负责调用目标方法。
InvocationHandler 接口:定义了动态代理的逻辑处理方法。
invoke
方法核心逻辑:- 接收调用参数(代理对象、方法和参数数组)。
- 调用目标方法(通过反射 API)。
- 可自定义处理前后逻辑。
代理生成流程 (以 JDK 为例)
- ClusterLoader:控制哪个类加载器加载代理类。
- Interface[]:传递目标接口。
- InvocationHandler:决定每次方法调用怎么处理。
代理对象使用示例
// 目标类interface Subject { void rent(); void hello(String str);}class RealSubject implements Subject { @Override void rent() { System.out.println("I want to rent my house"); } @Override void hello(String str) { System.out.println("hello: " + str); }}// 动态代理接口实现class DynamicProxy implements InvocationHandler { private RealSubject subject; constructor RealSubject subject) { this.subject = subject; } @Override public Object invoke(Object object, Method method, Object[] args) { System.out.println("调用前:" + method.getName()); method.invoke(subject, args); System.out.println("调用后"); return null; }}// 创建代理Subject subjectProxy = Proxy.newProxyInstance( DynamicProxy.class.getClassLoader(), RealSubject.class.getInterfaces(), new DynamicProxy(new RealSubject()));
测试输出示例
调用代理对象 method:
Proxy0before rent houseMethod: public abstract void com.xiaoluo SUBJECT rent ()I want to rent my houseafter rent housebefore rent houseMethod: public abstract void com.xiaoluo SUBJECT hello (java.lang.String)hello: worldafter rent house
JDK动态代理特点
- 动态生成代理对象,基于反射机制实现。
- 目标类需实现特定的接口。
- 透明度高,可通过反射观察代理逻辑。
CGILB 动态代理实现
区别与特点
CGILB 与 JDK 的主要区别:
CGILB 代理实现流程
导入必要库:
cglib-nodep-2.2.jar
(无需_asm.jar包)cglib-2.2.jar
(需配合_asm.jar包使用)
开发拦截器类:实现 MethodInterceptor
接口。
例子:TargetInterceptor 拦截器
import java.lang.reflect.Method;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class TargetInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] params, MethodProxy proxy) throws Throwable { System.out.println("拦截前:" + method.getName()); Object result = proxy.invokeSuper(obj, params); System.out.println("拦截后:" + result); return result; }}
- 创建动态代理:
// 定义类型对象public static final TargetObject TARGET_OBJECT = new TargetObject();// 实现 EnhancerEnhancer enhancer = new Enhancer();enhancer.setSuperclass(TARGET_OBJECT.getClass());enhancer.setCallback(new TargetInterceptor());TARGET_OBJECT = enhancer.create();// 调用方法System.out.println(TARGET_OBJECT.method1("mmm1"));System.out.println(TARGET_OBJECT.method2(100));System.out.println(TARGET_OBJECT.method3(200));
---## 动态代理的核心选型- **选择 JDK 动态代理**:如果目标对象已实现特定接口,且对动态代理的逻辑要求较为基础。- **选择 CGILB 动态代理**:如果需要更灵活的方法拦截,而目标对象无需实现接口,或需对方法执行过程增强功能。
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月18日 05时11分28秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
24.线程
2023-01-25
#Leetcode# 28. Implement strStr()
2023-01-25
$route 和 $router详解、区别、示例代码
2023-01-25
$scope angular在controller之外调用
2023-01-25
&和&&的区别
2023-01-25
064:vue+openlayers根据坐标来显示点、线段、圆形、多边形
2023-01-25
(ios实战)单个ViewControl适配不同ios版本xib文件实现
2023-01-25
(Leetcode-字符串-2) 字符串运算
2023-01-25
(type interface {}) to type string
2023-01-25
(五)java多线程之Lock类
2023-01-25
(十一) 构建dubbo分布式平台-dubbo简介
2023-01-25
asp.net MVC 强类型视图表单Ajax提交的注意事项
2023-01-25
Bailey Button Botas Ugg Baratas Corto Botas 5803 Casta?a Holgura Outlet GUANGXI SEDA ESTANCIA CALLB
2023-01-26
canvas设置文字阴影
2023-01-26