码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式-代理模式

时间:2019-07-03 17:03:27      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:and   llb   method   nbsp   字节码   icp   文件   ceo   java动态代理   

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

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

抽象角色

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

设计模式-代理模式

标签:and   llb   method   nbsp   字节码   icp   文件   ceo   java动态代理   

原文地址:https://www.cnblogs.com/panda28/p/10594701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!