设计模式之代理模式
代理模式
- 代理模式分为静态代理和动态代理.下图为静态代理结构图:
-
静态代理示例代码:
// 抽象主题接口 public interface Subject { void request(); } // 具体主题角色 public class RealSubject implements Subject{ @Override public void request() { System.out.println("真实对象处理请求..."); Random random = new Random(); try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } // 代理角色 public class Proxy implements Subject{ private Subject subject; public Proxy(Subject subject) { this.subject = subject; } @Override public void request() { System.out.println("代理对象开始处理请求..."); before(); subject.request(); after(); } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class ProxyTest { public static void main(String[] args) { Proxy proxy = new Proxy(new RealSubject()); proxy.request(); } }
-
JDK动态代理示例代码:
// 抽象接口 public interface Person { void findWork(); } // 具体对象 public class Worker implements Person{ @Override public void findWork() { System.out.println("打工人要找工作..."); } } // 代理类,实现的是InvocationHandler接口 public class JdkHr implements InvocationHandler { private Person target; public Person getInstance(Person person){ this.target = person; Class<? extends Person> targetClass = target.getClass(); return (Person) Proxy.newProxyInstance(targetClass.getClassLoader(), targetClass.getInterfaces(), this); } @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { before(); Object invoke = method.invoke(this.target, objects); after(); return invoke; } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class JdkProxyTest { public static void main(String[] args) { // 这一行设置保存程序运行时的动态代理类class文件,方便查看 System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true"); JdkHr hr = new JdkHr(); Person person = hr.getInstance(new Worker()); person.findWork(); } }
-
CGLib动态代理示例代码:
```java // 抽象接口 public interface Person { void findWork(); } // 具体对象 public class Worker implements Person{ @Override public void findWork() { System.out.println("打工人要找工作..."); } } // 代理类,实现的是MethodInterceptor接口 public class CglibHr implements MethodInterceptor { public Object getInstance(Class<?> clazz){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object obj = methodProxy.invokeSuper(o, objects); after(); return obj; } private void after() { System.out.println("proxy end..."); } private void before() { System.out.println("proxy start..."); } } // 测试 public class CglibProxyTest { public static void main(String[] args) { // 这一行设置保存程序运行时的动态代理类class文件 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "cglibProxy/"); CglibHr hr = new CglibHr(); Person person = (Person) hr.getInstance(Worker.class); person.findWork(); } } ```
-
JDK和CGLib动态代理对比:
- 静态代理和动态代理对比:
-
总结:
代理模式优点:将代理对象与真实被调用目标对象分离,降低了系统耦合性,扩展性好,并且可以增强目标对象的功能;
代理模式缺点:系统中类的数量增加,导致处理请求的速度变慢,增加了系统的复杂度.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探