Java 代理模式详细讲解

代理模式概述

代理模式的主要角色:

1. 静态代理

代码示例:

输出结果:

静态代理的优缺点:

2. 动态代理

JDK 动态代理

代码示例:

输出结果:

JDK 动态代理的优缺点:

3. CGLIB 动态代理

CGLIB 代理示例:

输出结果:

CGLIB 动态代理的优缺点:

代理模式应用场景

代理模式概述

代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过代理对象来控制对目标对象的访问。代理模式的核心思想是引入一个中介对象(代理),该代理对象负责控制对实际对象的访问,通常用于增强功能、控制访问权限或延迟初始化等场景。

代理模式的主要角色:
  1. 抽象主题(Subject):定义代理类和实际类的公共接口。
  2. 真实主题(RealSubject):实现了实际业务逻辑的类。
  3. 代理(Proxy):控制对真实对象的访问,可以增加额外的功能。

代理模式主要有两种实现方式:静态代理和动态代理。


1. 静态代理

在静态代理中,代理类和目标类都要实现相同的接口,代理类通过调用目标类的方法来实现功能扩展。

代码示例:
 

java

复制代码

// 抽象主题接口 public interface Subject { void request(); } // 真实主题类 public class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: 执行实际业务逻辑..."); } } // 代理类 public class Proxy implements Subject { private RealSubject realSubject; public Proxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void request() { System.out.println("Proxy: 在调用实际方法前可以做一些处理..."); realSubject.request(); // 调用真实对象的方法 System.out.println("Proxy: 在调用实际方法后可以做一些处理..."); } } // 客户端测试 public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); Proxy proxy = new Proxy(realSubject); proxy.request(); // 通过代理调用方法 } }

输出结果:
 

makefile

复制代码

Proxy: 在调用实际方法前可以做一些处理... RealSubject: 执行实际业务逻辑... Proxy: 在调用实际方法后可以做一些处理...

静态代理的优缺点:
  • 优点:可以在不修改原始类的前提下增加功能。
  • 缺点:每增加一个代理类都需要手动编写,代码量随之增加。

2. 动态代理

动态代理是代理模式的进化版,不需要为每个类手动编写代理类。动态代理在运行时生成代理对象,可以在运行时对方法进行增强。

在 Java 中,动态代理可以通过 JDK 的反射机制或 CGLIB 实现。

JDK 动态代理

JDK 提供了 java.lang.reflect.Proxy 类来创建动态代理,但它只能代理实现了接口的类。

代码示例:
 

java

复制代码

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 抽象主题接口 public interface Subject { void request(); } // 真实主题类 public class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: 执行实际业务逻辑..."); } } // 动态代理处理器 public class DynamicProxyHandler implements InvocationHandler { private Object target; public DynamicProxyHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Dynamic Proxy: 在方法调用前可以做一些处理..."); Object result = method.invoke(target, args); // 调用真实对象的方法 System.out.println("Dynamic Proxy: 在方法调用后可以做一些处理..."); return result; } } // 客户端测试 public class Client { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); // 创建动态代理对象 Subject proxy = (Subject) Proxy.newProxyInstance( realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), new DynamicProxyHandler(realSubject)); // 通过代理调用方法 proxy.request(); } }

输出结果:
 

yaml

复制代码

Dynamic Proxy: 在方法调用前可以做一些处理... RealSubject: 执行实际业务逻辑... Dynamic Proxy: 在方法调用后可以做一些处理...

JDK 动态代理的优缺点:
  • 优点:不需要为每个类编写代理类,节省代码量。
  • 缺点:只能代理实现了接口的类,无法代理普通类。

3. CGLIB 动态代理

CGLIB 是另一个用于实现动态代理的库,它通过生成目标类的子类来实现代理,能够代理没有实现接口的类。

CGLIB 代理示例:
 

java

复制代码

import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; // 真实主题类(没有实现接口) public class RealSubject { public void request() { System.out.println("RealSubject: 执行实际业务逻辑..."); } } // CGLIB 代理拦截器 public class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB Proxy: 在方法调用前可以做一些处理..."); Object result = proxy.invokeSuper(obj, args); // 调用真实对象的方法 System.out.println("CGLIB Proxy: 在方法调用后可以做一些处理..."); return result; } } // 客户端测试 public class Client { public static void main(String[] args) { // 创建 CGLIB 代理对象 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealSubject.class); enhancer.setCallback(new CglibProxy()); RealSubject proxy = (RealSubject) enhancer.create(); proxy.request(); // 通过代理调用方法 } }

输出结果:
 

yaml

复制代码

CGLIB Proxy: 在方法调用前可以做一些处理... RealSubject: 执行实际业务逻辑... CGLIB Proxy: 在方法调用后可以做一些处理...

CGLIB 动态代理的优缺点:
  • 优点:可以代理没有实现接口的类。
  • 缺点:由于是通过继承的方式代理,无法代理 final 类和 final 方法。

代理模式应用场景

  • 权限控制:通过代理类来控制对某些敏感对象的访问权限。
  • 性能优化:在代理中加入缓存逻辑,避免频繁调用开销大的方法。
  • 延迟加载:在需要时才创建实际对象,以节省资源。

代理模式的灵活性很高,可以适用于各种场景,包括权限管理、日志记录、事务处理等。

目录


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值