掌握Java代理模式:静态与动态代理详解
84 浏览量
更新于2024-10-27
收藏 25KB ZIP 举报
资源摘要信息: "代理模式是一种结构型设计模式,它允许你在不直接修改原对象代码的情况下,为其添加额外的功能。代理模式主要分为静态代理和动态代理两种。静态代理需要在程序运行之前,编写特定的代理类,而动态代理则是在运行时动态创建代理对象。动态代理又分为JDK动态代理和CGLIB动态代理。
首先,静态代理是指在程序运行之前,已经创建好代理类的实例。代理类和真实主题类都实现了同一个接口,代理类持有真实主题类的引用,并在调用真实主题方法前后添加额外的逻辑处理。这种代理模式简单直接,但是每个真实主题类都需要编写一个对应的代理类,代码冗余,不易维护。
动态代理则是在程序运行时动态生成代理对象。JDK动态代理要求被代理的类必须实现一个接口,JDK的java.lang.reflect.Proxy类提供了一个静态方法newProxyInstance,该方法可以在运行时动态创建接口的实现类实例。创建的代理类在调用接口方法时,可以拦截这些方法的调用,进行一些预处理、后处理工作。JDK动态代理只能为接口生成代理实例,如果被代理的类没有实现接口,那么就无法使用JDK动态代理。
CGLIB动态代理通过继承被代理类的方式实现代理。它使用了asm开源框架,能够在运行期动态生成指定类的子类,并在子类中增强方法。因此,如果被代理的类没有实现接口,也可以使用CGLIB进行代理。CGLIB创建的代理对象性能较好,但是它的代理过程比较复杂,需要处理的方法也会比较多。
在实际的Java开发中,Spring框架大量使用了动态代理技术,尤其是在实现AOP(面向切面编程)时。Spring提供了两种代理方式,即基于接口的JDK动态代理和基于类的CGLIB代理。Spring根据被代理的bean是否实现了接口,自动选择合适的代理方式。
总之,代理模式为对象的访问引入了一个间接层,可以控制对象的访问权限,甚至在不修改原有代码的情况下,为对象添加额外的处理逻辑,实现解耦合和增强功能。JDK动态代理和CGLIB动态代理各有优劣,适用场景不同,开发者需要根据具体需求选择合适的代理方式。"
【动态代理代码例子】:
```java
// JDK动态代理代码示例
public class JDKProxyExample {
interface HelloInterface {
void sayHello();
}
static class HelloClass implements HelloInterface {
@Override
public void sayHello() {
System.out.println("Hello, World!");
}
}
static class HelloInvocationHandler implements InvocationHandler {
private Object target;
public HelloInvocationHandler(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;
}
}
public static void main(String[] args) {
HelloInterface hello = new HelloClass();
HelloInvocationHandler handler = new HelloInvocationHandler(hello);
HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(
HelloClass.class.getClassLoader(),
new Class[]{HelloInterface.class},
handler
);
proxyHello.sayHello();
}
}
// CGLIB代理代码示例
public class CGLIBProxyExample {
static class HelloClass {
public void sayHello() {
System.out.println("Hello, World!");
}
}
static class HelloMethodInterceptor implements MethodInterceptor {
@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;
}
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloClass.class);
enhancer.setCallback(new HelloMethodInterceptor());
HelloClass hello = (HelloClass) enhancer.create();
hello.sayHello();
}
}
```
【压缩包子文件的文件名称列表】: Springlearn
从给出的文件名称"Springlearn"可以推测,压缩文件中可能包含了关于Spring框架的学习资料。由于"Springlearn"作为文件名称,并没有直接提供关于代理模式的额外信息,所以我们主要根据标题和描述来生成知识点。
2023-06-21 上传
2010-03-26 上传
2023-02-27 上传
2019-04-13 上传
2017-12-26 上传
2013-12-19 上传
2020-12-21 上传
2018-01-02 上传
2018-05-02 上传
沐风清扬
- 粉丝: 344
- 资源: 2
最新资源
- SSM动力电池数据管理系统源码及数据库详解
- R语言桑基图绘制与SCI图输入文件代码分析
- Linux下Sakagari Hurricane翻译工作:cpktools的使用教程
- prettybench: 让 Go 基准测试结果更易读
- Python官方文档查询库,提升开发效率与时间节约
- 基于Django的Python就业系统毕设源码
- 高并发下的SpringBoot与Nginx+Redis会话共享解决方案
- 构建问答游戏:Node.js与Express.js实战教程
- MATLAB在旅行商问题中的应用与优化方法研究
- OMAPL138 DSP平台UPP接口编程实践
- 杰克逊维尔非营利地基工程的VMS项目介绍
- 宠物猫企业网站模板PHP源码下载
- 52简易计算器源码解析与下载指南
- 探索Node.js v6.2.1 - 事件驱动的高性能Web服务器环境
- 找回WinSCP密码的神器:winscppasswd工具介绍
- xctools:解析Xcode命令行工具输出的Ruby库