### 浅析Java设计模式【3】——代理 #### 一、代理模式概述 代理模式是一种行为型设计模式,主要用于在客户端与目标对象之间起到一个中介的作用,通过代理对象来控制对目标对象的访问。代理模式的核心在于它可以提供额外的功能或逻辑处理,如日志记录、性能监控、权限验证等,而这些功能并不会直接影响到目标对象本身的职责。 #### 二、代理模式的关键概念 根据代理模式创建代理对象的方式不同,可以将其分为静态代理、动态代理和CGLIB代理三种类型。 ##### 1. 静态代理 静态代理的特点是在编译时期就已经定义好了代理类和被代理类之间的关系,代理类通常实现与被代理类相同的接口。这种方式类似于现实生活中的企业与法律顾问的关系,即在出现具体问题之前已经建立了代理关系。 **示例代码解析:** ```java public interface Loginable { void login(); } @Slf4j public class LoginService implements Loginable { @Override public void login() { try { Thread.sleep(new Random().nextInt(5000)); } catch (InterruptedException e) { e.printStackTrace(); } log.error("登陆成功"); } } @Slf4j public class LoginServiceProxy implements Loginable { private Loginable loginable; public LoginServiceProxy() { } public LoginServiceProxy(Loginable loginable) { this.loginable = loginable; } @Override public void login() { long start = System.currentTimeMillis(); log.error("start proxy: " + start); loginable.login(); long end = System.currentTimeMillis(); log.error("end proxy: " + end); log.error("spend all time: " + (end - start) + " ms."); } } ``` 在上述示例中,`LoginService` 是实现登录功能的具体类,而 `LoginServiceProxy` 则是一个代理类,用于记录登录操作的耗时。这种代理模式的优势在于可以通过代理类在目标方法调用前后添加额外的功能,如本例中的日志记录。但缺点也很明显:当被代理对象发生变化时,需要修改代理类的代码。 ##### 2. 动态代理 与静态代理不同,动态代理是在运行时动态创建代理对象的一种机制。这种方式允许在运行期间根据不同的需求创建不同的代理实例,更加灵活。Java 提供了两种动态代理机制:基于接口的动态代理和基于类的动态代理(CGLIB)。 - **基于接口的动态代理**:使用 `java.lang.reflect.Proxy` 类和 `java.lang.reflect.InvocationHandler` 接口来实现。 - **基于类的动态代理(CGLIB)**:使用第三方库 CGLIB 来实现代理,适用于无法使用基于接口的动态代理的情况。 **基于接口的动态代理示例代码:** ```java public interface Loginable { void login(); } @Slf4j public class LoginService implements Loginable { @Override public void login() { log.error("登陆成功"); } } @Slf4j public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } public Object getProxyInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log.error("start proxy"); Object result = method.invoke(target, args); log.error("end proxy"); return result; } } ``` 在以上示例中,`DynamicProxy` 类实现了 `InvocationHandler` 接口,并通过 `Proxy.newProxyInstance` 方法创建了动态代理对象。通过这种方式可以在运行时动态地添加功能,无需修改现有代码。 #### 三、代理模式的应用场景 代理模式广泛应用于以下几种场景: 1. **远程代理**:为一个位于不同地址空间的对象提供一个本地代理。 2. **虚拟代理**:根据需要创建一个资源消耗较大的对象。 3. **缓存代理**:为某些操作的结果提供临时的存储空间。 4. **智能引用代理**:当对象被引用时,提供一些额外的操作或检查。 代理模式作为一种常见的设计模式,能够有效地帮助我们在不改变原有代码的基础上增加额外的功能,提高代码的复用性和灵活性。通过合理选择静态代理和动态代理,可以更好地满足不同场景下的需求。




















剩余6页未读,继续阅读


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


最新资源
- 200smart自动上料机:3轴伺服控制与西门子Smart系列PLC及触摸屏程序参考 PLC 参考
- 一个使用 Python 编写的电影评分与评论爬虫源码,以 IMDb 为例
- 三菱PLC与威纶触摸屏在伺服电机控制及多设备互联的应用详解
- 【Android应用源码】TXT文本阅读器源码.zip
- 【Android应用源码】txt阅读器.zip
- 【Android应用源码】twitter客户端.zip
- 【Android应用源码】UITableView ios风格控件.zip
- 【Android应用源码】UI设计之 仿做蘑菇街UI设计 源码.zip
- 【Android应用源码】umeng_sdk_201312301505_fb_update.zip
- 【Android应用源码】-Universal-Image-Loader-master.zip
- 【Android应用源码】umeng_sdk_201312301505_update.zip
- 【Android应用源码】umeng_sdk_201312301505_fb_update_analytics.zip
- 【Android应用源码】UseIntentRebackHomeSample.zip
- 【Android应用源码】upload.zip
- 【Android应用源码】upload1.zip
- 【Android应用源码】VerticalSeekbar.zip


