
Java静态代理与动态代理实例解析及源码
下载需积分: 10 | 16KB |
更新于2025-07-10
| 59 浏览量 | 举报
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
最新资源
- 谭浩强版C++编程实操题解及上机指导
- 华为J2EE面试题大揭秘,网络试题解析
- 《计算机与网络英汉大词典》专业词典下载
- C#委托应用实例解析
- SwiSHmax:创新的Flash动画编辑工具
- 全面掌握SQL Server 2005:培训教程与面试题解析
- DB2在Linux系统上的安装与基本使用指南
- 优化后的红色模板:hzhost5.2版本完善指南
- C#.NET开发OA系统核心功能与应用
- 后台系统美工与功能评测
- J2ME编程教程:权威指南与IBM专家经验分享
- AJAX-ValidatorCallout控件的简易使用示例
- 美观实用的JS日期时间选择器介绍
- 压缩包子文件处理技术介绍
- JDK1.6重点新特性深入分析与应用
- MySQL参考手册详细解析关键字功能与常见问题
- 扩展 eclipse 代码折叠功能的 myeclipse 插件
- ASP.NET实现具地区查询功能的留言板系统
- wodig 4 源代码分析与文件压缩技术
- 全面解析TreeListView控件在C#中的应用技巧
- 深入了解SSH框架集成:Struts+Spring+Hibernate实战案例
- 深入解析Windows驱动程序模型设计源代码
- 轻松验证数据完整性:md5/SHA/CRC哈希工具
- C/C++函数库参考大全(chm中文版)