设计模式-代理模式

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

静态代理模式:由程序员自己创建代理类源码,再编译代理类。也就是程序运行前就已经存在代理类的字节码文件,代理类与委托类的关系在运行前就确定了。

抽象角色

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这种非反射机制快速的调用到代理类中的方法

posted on   菜鸟28  阅读(114)  评论(0编辑  收藏  举报

编辑推荐:
· 从 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的设计差异
· 三行代码完成国际化适配,妙~啊~
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示