Java 代理设计模式
代理模式
模式定义
代理模式是为目标对象创建代理对象以提供一种代理机制,让代理对象能控制目标对象的访问,并且可以在不改变目标对象的情况下为目标对象添加额外的功能
模式分类
静态代理
在程序编译期静态地为目标类创建代理类
动态代理
在程序运行期运用反射机制动态地为目标类创建代理类(Spring AOP 采用动态代理)
UML 类图

静态代理代码示例
// 定义一个接口
interface Rent {
void rent();
}
// 定义一个实际对象
class Host implements Rent {
@Override
public void rent() {
System.out.println("房东出租房子。");
}
}
// 定义一个静态代理对象
class StaticProxy implements Rent {
private Rent rent;
public StaticProxy(Rent rent) {
this.rent = rent;
}
@Override
public void rent() {
System.out.println("中介带房客看房子。");
rent.rent();
}
}
// 使用代理
public class StaticProxyModelTest {
public static void main(String[] args) {
Rent host = new Host();
Rent proxy = new StaticProxy(host);
proxy.rent(); // 输出:中介带房客看房子。房东出租房子。
}
}
在这个例子中,Host 是实际对象,它实现了 Rent 接口。StaticProxy 是静态代理对象,它持有实际对象的引用,并在其 rent 方法中包含了额外的逻辑(如显示中介带看房子的信息)。
动态代理示例
// 定义一个接口
interface Rent {
void rent();
}
// 定义一个实际对象
class Host implements Rent {
@Override
public void rent() {
System.out.println("房东出租房子。");
}
}
// 代理处理器
class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行前的操作...");
Object result = method.invoke(target, args);
System.out.println("执行后的操作...");
return result;
}
}
// 使用动态代理
public class DynamicProxyModelTest {
public static void main(String[] args) {
Rent host = (Rent) Proxy.newProxyInstance(
Rent.class.getClassLoader(),
new Class<?>[]{Rent.class},
new ProxyInvocationHandler(new Host()));
host.rent(); // 输出:执行前的操作...房东出租房子。执行后的操作...
}
}
在实际编程中,选择使用静态代理还是动态代理取决于具体的应用场景和对性能的要求。静态代理更适合于那些不需要在运行时动态创建代理的场景,而动态代理则更适合于需要在运行时根据不同情况进行处理的场景。
优缺点
优点
- 代理模式可以提供控制访问、延迟加载、日志记录等功能。
- 代理模式可以提高系统的灵活性和可扩展性。
- 代理模式可以隐藏对象的创建细节,使系统更加优雅。
缺点
- 如果代理对象过于复杂,可能会导致代码难以理解和维护。
- 代理模式可能会引入性能开销,特别是如果代理逻辑较为复杂的话。
使用场景
远程代理
为一个位于不同网络计算机的对象提供一个本地的代理(如本地网盘)
虚拟代理
如果需要创建一个消耗较大的对象,先创建一个消耗较小的对象来表示,真实对象只在需要时才被真实创建(如图片显示)
安全代理
用来控制不同种类客户对真实对象的访问权限
智能指引
主要用于调用目标对象时,代理附加一些额外的处理功能(如GC垃圾回收)
延迟加载
为了提高系统的性能,延迟对目标对象的加载(如MyBatis 的延时加载)

浙公网安备 33010602011771号