设计模式-代理模式
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
静态代理模式:由程序员自己创建代理类源码,再编译代理类。也就是程序运行前就已经存在代理类的字节码文件,代理类与委托类的关系在运行前就确定了。
抽象角色
public interface InterfaceObject { void sayHello(); }
目标角色
public class RealObject implements InterfaceObject{ public void sayHello() { System.out.println("Hello World..."); } }
代理角色
public class ProxyObject implements InterfaceObject{ private RealObject realObject; public ProxyObject(RealObject realObject){ this.realObject = realObject; } public void sayHello() { System.out.println("Before Hello World..."); realObject.sayHello(); System.out.println("After Hello World..."); } }
动态代理:在实现阶段不用关心代理类,而在运行阶段才指定是哪一个对象
JDK动态代理
public class ProxyInvocationHandler implements InvocationHandler{ private Object target;//对真实对象的引用 public ProxyInvocationHandler(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before DynamicProxy..."); //执行方法... method.invoke(target,args); System.out.println("After DynamicProxy..."); return null; } }
//动态代理(JDK动态代理) InterfaceObject realObject = new RealObject();//目标对象 //创建与代理对象相关连的InvocationHandler InvocationHandler handler = new ProxyInvocationHandler(realObject); InterfaceObject proxy1 = (InterfaceObject) Proxy.newProxyInstance(InterfaceObject.class.getClassLoader(), new Class<?>[]{InterfaceObject.class}, handler); proxy1.sayHello();
底层原理:
查看源码Class<?> cl = getProxyClass0(loader, intfs);产生了代理类$Proxy0 extends Proxy implements InterfaceObject(存放在内存中)
发编译查看代理类的构造方法调用了父类Proxy的构造方法super(paramInvocationHandler);
protected Proxy(InvocationHandler h) { Objects.requireNonNull(h); this.h = h; }
静态代码块得到了代理方法 m3 = Class.forName("proxy.InterfaceObject").getMethod("sayHello", new Class[0]);
代理类的sayHello()方法直接调用了InvocationHandler中的invoke方法,并把m3传了进去this.h.invoke(this, m3, null);
代理类继承了Proxy类,所以Java动态代理只能对接口进行代理(java不支持多继承)
cglib动态代理
public class ProxyInterceptor implements MethodInterceptor{ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { proxy.invokeSuper(obj, args); return null; } }
//cglib动态代理 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealObject.class); enhancer.setCallback(new ProxyInterceptor()); RealObject realObject2 = (RealObject) enhancer.create(); realObject2.sayHello();
cglib利用继承的方式动态创建了被代理类的子类,通过ASM生成父类中所有public非final修饰的方法,实现了代理
invokeSuper方法以fastclass这种非反射机制快速的调用到代理类中的方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~