理解动态代理:从静态代理到JDK、CGLIB代理

需积分: 0 0 下载量 113 浏览量 更新于2024-08-03 收藏 168KB DOCX 举报
"本文主要介绍了代理模式中的静态代理和动态代理,强调了它们在软件设计中的重要性,特别是在不修改原有代码的情况下扩展功能。代理模式遵循开闭原则,允许对扩展开放,对修改关闭。文章首先阐述了代理模式的基本概念,然后通过具体的例子解释了静态代理的工作原理,最后提到了动态代理的概念,但未给出详细实现。" 在软件设计中,代理模式是一种常见且实用的设计模式,它允许我们创建一个代理对象来代表另一个对象,从而在不修改原对象代码的情况下添加额外的功能或控制访问。代理模式的核心思想是将原始对象与代理对象关联,通过代理对象间接调用原始对象的方法,实现对原始对象功能的扩展。 一、代理模式是什么? 代理模式是一种结构型设计模式,其核心是通过代理对象来封装目标对象,使得代理对象可以提供比目标对象更多的功能。代理对象通常执行一些辅助任务,如日志记录、权限检查、缓存等,同时保持对目标对象原有功能的透明访问。 二、静态代理 静态代理在编程时就已经明确指定了代理关系,即代理类与被代理类在编译时就需要知晓对方。以下是一个简单的静态代理示例: 首先,定义一个接口`Star`,表示明星,包含一个`skill`方法来表示明星的才艺展示。 ```java public interface Star { void skill(); } ``` 然后,创建一个具体的明星对象`GeGe`,它实现了`Star`接口。 ```java public class GeGe implements Star { private String name; public GeGe() {} public GeGe(String name) { this.name = name; } @Override public void skill() { System.out.println(name + "在唱歌"); System.out.println(name + "在跳舞"); System.out.println(name + "在说唱"); } } ``` 接着,创建一个静态代理类`Agent`,同样实现`Star`接口,通过持有`Star`类型的成员变量来代理真实明星的行为。 ```java public class Agent implements Star { private Star target; public Agent(Star target) { this.target = target; } @Override public void skill() { // 在调用真实对象的skill方法前,可以添加额外操作,如记录日志 System.out.println("开始演出"); target.skill(); // 在调用真实对象的skill方法后,也可以添加额外操作,如清理场地 System.out.println("演出结束"); } } ``` 在这个例子中,`Agent`作为静态代理,它在调用`GeGe`的`skill`方法前后添加了额外的逻辑。 三、动态代理 动态代理则是在运行时动态生成代理类和代理对象,这样就不需要为每个目标对象都创建一个对应的代理类。Java中通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现动态代理。动态代理的好处在于灵活性,可以在运行时根据需要创建代理对象,而不需要预先编写多个代理类。 虽然在给定的文件中没有详细解释动态代理的实现,但通常步骤如下: 1. 定义一个接口,让目标对象和代理对象共同实现。 2. 创建一个实现`InvocationHandler`接口的类,处理代理对象的调用。 3. 使用`Proxy.newProxyInstance()`方法生成动态代理对象,传入接口类的类加载器、接口列表和自定义的`InvocationHandler`实例。 4. 通过动态代理对象调用方法,实际上会触发`InvocationHandler`的`invoke()`方法。 代理模式的应用非常广泛,尤其是在需要扩展已有系统功能或控制第三方库的使用时。通过合理地运用静态代理和动态代理,开发者可以更加灵活地管理代码结构,提高代码的可维护性和可扩展性。