
Java静态代理与动态代理实例解析及源码
下载需积分: 10 | 16KB |
更新于2025-07-10
| 132 浏览量 | 举报
1
收藏
在Java编程语言中,代理模式是一种重要的设计模式,它允许我们创建一个代理类来代表另一个对象执行操作。代理类在客户端和目标对象之间起到中介作用。按照代理的创建时机和方式,可以分为静态代理和动态代理。以下是从给定文件信息中提取出的相关知识点。
### 静态代理
静态代理是指在编译期就确定了代理类,并且在代码中明确地定义了代理类,它与目标类都实现同一个接口或继承同一个父类。静态代理的主要优点是易于理解、易于实现,同时也易于调试。但是它的缺点也很明显,当需要代理的类非常多时,就会产生大量的代理类,导致代码冗余,不易维护。
**静态代理的实现步骤通常包括:**
1. **定义一个共同的接口:** 所有的目标类和代理类都遵循这个接口,以确保它们拥有相同的方法签名。
2. **创建目标类:** 实现共同的接口,并提供业务逻辑实现。
3. **创建代理类:** 也实现共同的接口,并在实现接口方法的同时,在内部调用目标类的相关方法。
4. **客户端使用:** 客户端通过代理类来调用目标类的方法。
**静态代理示例代码分析:**
假设有一个共同接口`UserService`,一个目标类`UserServiceImpl`和一个代理类`UserProxy`,客户端代码如下:
```java
// 共同接口
public interface UserService {
void addUser();
}
// 目标类实现共同接口
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
// 实际的业务逻辑
}
}
// 代理类也实现共同接口
public class UserProxy implements UserService {
private UserService userService; // 持有目标类的引用
public UserProxy(UserService userService) {
this.userService = userService;
}
@Override
public void addUser() {
// 在调用目标类方法前可以做一些预处理
System.out.println("Before add user");
userService.addUser(); // 调用目标类的方法
// 在调用目标类方法后可以做一些后续处理
System.out.println("After add user");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserProxy proxy = new UserProxy(userService);
proxy.addUser();
}
}
```
### 动态代理
动态代理是指在运行期动态地生成代理类,与静态代理相比,动态代理不需要为每一个目标类编写一个代理类。动态代理通常有两种实现方式:基于接口的动态代理和基于类的动态代理。基于接口的动态代理由Java内置的`java.lang.reflect.Proxy`类实现,基于类的动态代理由`java.lang.reflect.InvocationHandler`接口和`java.lang.reflect.Proxy`类共同实现。
**动态代理的优点:**
1. **减少代码量:** 不需要为每一个目标类编写代理类,从而减少重复代码。
2. **灵活性高:** 动态生成的代理类可以灵活地应用到各种不同的目标类中。
**动态代理的实现步骤通常包括:**
1. **实现`InvocationHandler`接口:** 实现`invoke`方法,定义了代理对象的业务逻辑。
2. **使用`Proxy.newProxyInstance`方法:** 通过目标类的类加载器、实现的接口类型以及`InvocationHandler`实例生成代理对象。
3. **客户端使用代理对象:** 客户端通过得到的代理对象调用目标方法。
**动态代理示例代码分析:**
```java
// 目标类
public class RealService implements HelloService {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
}
// 定义接口
public interface HelloService {
void sayHello(String name);
}
// 实现InvocationHandler接口
public class MyInvocationHandler implements InvocationHandler {
private Object target; // 目标对象
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method");
Object result = method.invoke(target, args); // 调用目标对象方法
System.out.println("After method");
return result;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
HelloService realService = new RealService();
InvocationHandler handler = new MyInvocationHandler(realService);
// 生成动态代理对象
HelloService proxyService = (HelloService) Proxy.newProxyInstance(
HelloService.class.getClassLoader(),
new Class[]{HelloService.class},
handler);
proxyService.sayHello("World");
}
}
```
在上述代码中,我们首先定义了一个`HelloService`接口以及它的实现类`RealService`,然后创建了`MyInvocationHandler`类实现`InvocationHandler`接口。在客户端代码中,我们通过`Proxy.newProxyInstance`方法创建了一个动态代理类的实例,并通过代理实例调用目标方法。
通过以上示例代码,我们可以看到静态代理和动态代理的实现方式及其各自的特点和使用场景。静态代理由于需要编写具体的代理类,虽然直观但会增加代码量和维护成本;而动态代理则减少了这些开销,能够提供更灵活和高效的代理解决方案。在实际应用中,应根据具体的需求来选择合适的代理模式。
相关推荐










SZleoWang
- 粉丝: 123
最新资源
- Struts API 中文版手册使用指南
- ASP猜数字游戏实现与代码解析
- MyQQ局域网通讯源代码分析
- VclSkin皮肤样式包下载:233种样式任你选
- J2ME手机游戏开发实践教程
- HtmlAgilityPack:适用于.NET的高效HTML分析开源库
- Java面试题集锦:笔试面试必备题目增加版
- Struts2自定义拦截器实战教程
- C#实现窗体自动闪烁效果的编程教程
- SSH框架购物车源代码实现与数据库SQL2000应用
- JAVA SWING图形界面编程实战教程
- VB发声计算器实现及使用教程
- 基于IP的天气信息查询系统PHP实现
- 大学时期开发的VC五子棋带智能下棋功能
- VB编程:创建一个可爱的音乐播放器
- Delphi WebService 示例教程与应用实例
- 《ASP.NET技术方案宝典》光盘资料更新
- 网络设计大作业完整版分享
- 机械专业英语常用词汇集锦
- 深入探讨VB中的ADO数据库编程技巧与应用
- PHP入门教程:新手必备编程指南
- 31个实用PLSQL编程示例精讲
- Max场景制作助手2.0 Final版本发布
- Linux下电信计费系统的C/C++开发指南