### Java动态代理(JDK和cglib) #### 一、代理模式概述 代理模式是一种结构型设计模式,其中代理类含有一个对真实主题对象的引用,这样代理对象就可以执行一些预备或清理工作,并将真正的调用传递给真实主题对象。 在Java中,代理模式的应用非常广泛,特别是在框架级开发中,例如AOP(面向切面编程)中的通知(Advice)、事务管理等方面都离不开代理技术的支持。根据代理对象创建的时间不同,代理又可分为静态代理和动态代理两种类型。 #### 二、静态代理 静态代理是指在程序运行前,代理类的`.class`文件就已经存在的情况。具体来说,静态代理需要程序员事先手动编写代理类,或者通过一些工具来自动生成代理类的源代码,然后进行编译。 **示例代码:** 1. **Count.java** - 定义了一个账户接口: ```java public interface Count { void queryCount(); void updateCount(); } ``` 2. **CountImpl.java** - 实现了上述接口,包含具体的业务逻辑: ```java public class CountImpl implements Count { @Override public void queryCount() { System.out.println("查看账户方法"); } @Override public void updateCount() { System.out.println("修改账户方法"); } } ``` 3. **CountProxy.java** - 代理类,用于增强CountImpl实现类: ```java public class CountProxy implements Count { private CountImpl countImpl; public CountProxy(CountImpl countImpl) { this.countImpl = countImpl; } @Override public void queryCount() { System.out.println("事务处理之前"); countImpl.queryCount(); System.out.println("事务处理之后"); } @Override public void updateCount() { System.out.println("事务处理之前"); countImpl.updateCount(); System.out.println("事务处理之后"); } } ``` 4. **TestCount.java** - 测试类: ```java public class TestCount { public static void main(String[] args) { CountImpl countImpl = new CountImpl(); CountProxy countProxy = new CountProxy(countImpl); countProxy.updateCount(); countProxy.queryCount(); } } ``` 在这个例子中,我们通过CountProxy代理类实现了对CountImpl类的增强,即在查询和更新账户方法之前和之后添加了一些额外的操作。 #### 三、动态代理 动态代理则是在程序运行过程中动态创建代理类的过程。Java提供了两种实现动态代理的方式: 1. **JDK动态代理** - 基于接口实现的动态代理。 2. **CGLIB动态代理** - 基于继承实现的动态代理。 **JDK动态代理实现:** JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。`Proxy`类提供了创建动态代理类的方法,而`InvocationHandler`接口则用于定义代理对象的调用处理逻辑。 **示例代码:** ```java public class JdkProxyDemo { public static void main(String[] args) { // 目标对象 Count target = new CountImpl(); // 创建InvocationHandler实例 InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("事务处理之前"); Object result = method.invoke(target, args); System.out.println("事务处理之后"); return result; } }; // 创建代理对象 Count proxy = (Count) Proxy.newProxyInstance( Count.class.getClassLoader(), new Class<?>[]{Count.class}, handler); // 调用代理对象的方法 proxy.updateCount(); proxy.queryCount(); } } ``` #### 四、CGLIB动态代理 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它可以在运行时动态生成一个目标类的子类。当目标对象没有实现接口时,可以使用CGLIB来实现代理。 **示例代码:** ```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxyDemo { public static void main(String[] args) { // 目标对象 Count target = new CountImpl(); // 创建Enhancer实例 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事务处理之前"); Object result = proxy.invokeSuper(obj, args); System.out.println("事务处理之后"); return result; } }); // 创建代理对象 Count proxy = (Count) enhancer.create(); // 调用代理对象的方法 proxy.updateCount(); proxy.queryCount(); } } ``` 总结而言,无论是静态代理还是动态代理,其核心思想都是通过代理类对真实主题对象的行为进行增强。在实际应用中,动态代理由于其灵活性和可扩展性,往往更加受欢迎。而在动态代理中,JDK动态代理适用于有接口的情况,而CGLIB则适用于没有接口的情况。选择合适的代理方式能够更好地满足不同的应用场景需求。


















剩余8页未读,继续阅读


- 粉丝: 0
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- vcos_components_configs-智能车资源
- 中职计算机教学中存在的问题及对策探思.docx
- 数字图像处理实验指导说明书zqd.doc
- lanqiao-蓝桥杯资源
- 汇编语言-汇编语言资源
- 通信工程中多网融合技术的探析.docx
- 基于华为云计算技术的多课程教学平台的构建.docx
- cotParam-C语言资源
- klogging-C++资源
- VC数据挖掘在客户关系管理中的实际应用.doc
- (源码)基于Pytorch的CenterNet目标检测模型实现.zip
- 完成Java面向对象程序设计方案实验课的心得体会.doc
- 中职计算机蓝领人才培养的思考与探索.docx
- 海外工程项目管理面临的挑战与对策.docx
- 基于智慧城市的快递寄件系统研究.docx
- 人工智能改善生活.docx


