zoukankan      html  css  js  c++  java
  • 【Java Proxy Pattern】Java的代理模式

    Java的代理模式

    什么是代理模式[Proxy Pattern]?

    代理模式就是为了在其他对象访问一个对象时,提供一种代理,而不是直接访问该对象。
    有点像在外部进行了一层包裹。
    这个代理模式,和装饰器模式Decorator Pattern的区别在于proxy是为了控制,decorator是为了增强功能。

    静态代理和动态代理

    • 静态代理类就是类已经生成好了,而不是在程序运行时生成的。
      静态一旦写完,一般就代理一个固定的类。

    • 动态代理类在很多场景下在client和target之间充当一个中介者的角色。动态代理类时在运行时生成字节码,

    接口

    /**
    * Interface IVehicle.
    */
    public interface IVehicle {
        public void start();
        public void stop();
        public void forward();
        public void reverse();
        public String getName();
    }
    

    target class

    /**
    * Class Car
    */
    public class Car implements IVehicle {
        private String name;
        public Car(String name) {this.name = name;}
        public void start() {
        System.out.println("Car " + name + " started");
    }
    // stop(), forward(), reverse() implemented similarly.
    // getName() not shown.
    }
    

    client

    /**
    * Class Client1.
    * Interacts with a Car Vehicle directly.
    */
    public class Client1 {
        public static void main(String[] args) {
            IVehicle v = new Car("Botar");
            v.start();
            v.forward();
            v.stop();
        }
    }
    

    代理类

    /**
    * Class VehicleProxy.
    */
    public class VehicleProxy implements IVehicle {
        private IVehicle v;
        public VehicleProxy(IVehicle v) {this.v = v;}
        public void start() {
        System.out.println("VehicleProxy: Begin of start()");
        v.start();
        System.out.println("VehicleProxy: End of start()");
        }
        // stop(), forward(), reverse() implemented similarly.
        // getName() not shown.
    }
    

    代理类的client2

    /**
    * Class Client2.
    * Interacts with a Car Vehicle through a VehicleProxy.
    */
    public class Client2 {
        public static void main(String[] args) {
            IVehicle c = new Car("Botar");
            IVehicle v = new VehicleProxy(c);
            v.start();
            v.forward();
            v.stop();
        }
    }
    

    动态代理

    • 动态代理是在运行时实现了目标类的一系列接口
    • 代理instance是代理类的一个instance
    • 每一个代理实例都会调用一个实现InvoicationHandler接口的handler object
    • 代理实例上的方法调用通过他的代理接口调用实例的invocation handler
    • 代理类的创建是通过 java.lang.reflect.Proxy
    • 代理类的名字是以$Proxy开头
    • 当代理类创建的时候, 所指定的接口会被实现。
    • 当代理类创建时实现了所有接口, 代理类调用 getInterfaces()会返回一个包含所有接口的接口数组。
    • 每一个代理类有一个public的构造函数 需要一个实现InvocationHandler接口的handler 作为参数。

    getProxyClass

     public static Class getProxyClass(ClassLoader loader,
    Class[] interfaces)
    throws IllegalArgumentException
    
    

    通过类加载器,接口数组,返回一个代理类。

    Proxy构造一个Proxy 实例

    protected Proxy(InvocationHandler ih)
    
    

    isProxyClass 判断是否一个代理类。

    public static boolean isProxyClass(Class c)
    
    

    newProxyInstance

     public static Object newProxyInstance(ClassLoader loader,
    Class[] interfaces,
    InvocationHandler ih)
    throws IllegalArgumentException
    

    以下2个写法是等价的

    Proxy.newProxyInstance(cl, interfaces, ih);
    
    Proxy.getProxyClass(cl,
    interfaces).getConstructor(new Class[] {
    InvocationHandler.class }).newInstance(new
    Object[] {ih});
    

    getInvocationHandler 从指定的proxy 返回一个调用invocation handler

    public static InvocationHandler getInvocationHandler
    (Object proxy)
    throws IllegalArgumentException
    

    invoke 处理代理实例上的方法调用并且返回object
    proxy是代理类,method是方法名,args是方法对应的参数

    public Object invoke(Object proxy, Method method,
    Object[] args) throws Throwable
    

    所以这样一来,handler就是这样

    /**
    * Class VehicleHandler.
    */
    public class VehicleHandler implements InvocationHandler {
        private IVehicle v;
        public VehicleHandler(IVehicle v) {this.v = v;}
        public Object invoke(Object proxy, Method m, Object[] args)
        throws Throwable {
            System.out.println("Vehicle Handler: Invoking " +
            m.getName());
            return m.invoke(v, args);
        }
    }
    
    

    代理类的 client3

    /**
    * Class Client3.
    * Interacts with a Car Vehicle through a dynamically
    * generated VehicleProxy.
    */
    public class Client3 {
        public static void main(String[] args) {
            IVehicle c = new Car("Botar");
            ClassLoader cl = IVehicle.class.getClassLoader();
            IVehicle v = (IVehicle) Proxy.newProxyInstance(cl,
            new Class[] {IVehicle.class}, new VehicleHandler(c));
            v.start();
            v.forward();
            v.stop();
        }
    }
    
  • 相关阅读:
    SIMULINK动态仿真集成环境
    自带计算器
    零知识证明
    2012年软件大赛校内选拔赛
    使用VC2005 Express版时找不到msvcr80d.dll文件
    DirectX 90 3D SetRenderState 设置渲染状态
    ofstream和ifstream详细用法
    IncrediBuild 进行联合编译
    环形缓冲区,魔戒lordrings,boost的circular_buffer
    vector中resize和reserve接口的异同
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/13572388.html
Copyright © 2011-2022 走看看