• 如何理解代理?


    一、本节主要点

    1. 代理的概念
    2. 静态代理和动态代理

    代理的概念

    什么是代理呢?

    代理,就是一个角色代表另一个角色去完成某件事。

    比如,你肚子饿了,又懒得出去吃饭,这时候,你的朋友正好要出去,你让他帮忙打包。那他就是代理类。你就是委托他去做事。

    这个代理类在帮你打包的同时,他还可以自己打包,或者顺便去买包烟。

    那这个代理类有什么作用呢?

    就是完成目标类 之前可以做点其他什么的。之后可以做点什么。

    静态代理

    在运行之前,代理的类已经确定。

    例子如下:

    1、Pack 接口

    public interface Pack {
        public void giveMePack();
    }

    2、PackImpl 类

    public class PackImpl implements Pack {
        @Override
        public void giveMePack() {
            System.out.println("帮我打包吧,中午下雨啊");
        }
    }

    3 proxy 代理类

    /**代理类
     * Created by hp on 14-7-27.
     */
    public class Proxy implements Pack {
    
        public PackImpl pack;
    
        public Proxy(PackImpl pack) {
            this.pack = pack;
        }
    
        @Override
        public void giveMePack() {
            System.out.println("哥去买包烟先,再帮你打包");
            pack.giveMePack();
            System.out.println("垃圾太多了,倒掉吧");
        }
    }

    4、ClientText 类

    public class ClientText {
        public static void main(String[] args) {
            PackImpl pack = new PackImpl();
            Proxy proxy = new Proxy(pack);
            proxy.giveMePack();
    
        }
    }

    以上就是静态代理的实现代码。它有一个特点:

    一个代理类只服务于一个接口。

    这样如果有许多这样的代理,那就有很多的代理类出现。所以,最好是有一个代理类可以完成全部的代理功能。这就是下面要讲的动态代理了。

    动态代理

    解释一下,动态代理就是在程序运行中由Java的反射机制动态生成。

    先看一下JDK对动态代理的支持,java.lang.reflect 包中的 InvocationHandler 接口和 Proxy 类。

    1、InvocationHandler 接口

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

    Object proxy:被代理的对象。 
         Method method:要调用的方法 
         Object[] args:方法调用需要的参数

    2、Proxy类

    这个是完成代理的操作类。其中有一个方法是这样的

    ClassLoader loader:类加载器 
         Class<?>[] interfaces:得到全部的接口 
         InvocationHandler h:得到InvocationHandler接口的子类实例

    public static Object newProxyInstance(ClassLoader loader,
                          Class<?>[] interfaces,
                          InvocationHandler h)
        throws IllegalArgumentException
        {
        if (h == null) {
            throw new NullPointerException();
        }
    
        /*
         * Look up or generate the designated proxy class.
         */
        Class cl = getProxyClass(loader, interfaces);
    
        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            Constructor cons = cl.getConstructor(constructorParams);
            return (Object) cons.newInstance(new Object[] { h });
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString());
        } catch (IllegalAccessException e) {
            throw new InternalError(e.toString());
        } catch (InstantiationException e) {
            throw new InternalError(e.toString());
        } catch (InvocationTargetException e) {
            throw new InternalError(e.toString());
        }
        }

    代理类实例:

    /**
     * JDK 的动态代理
     * Created by hp on 14-7-27.
     */
    public class DynamicProxy implements InvocationHandler {
    
        private Object object;
    
        public Object getProxyInterface(Object object) {
            this.object = object;
            // 获取代理对象
            Object o = Proxy.newProxyInstance(object.getClass().getClassLoader(),
                    object.getClass().getInterfaces(), this);
            return o;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("哥去买包烟先,再帮你打包");
            Object result = method.invoke(object, args);
            System.out.println("垃圾太多了,倒掉吧");
            return result;
        }
    }

    从JDK动态代理可以看出。代理类的变化:

    1、实现了InvocationHandler接口。

    2、把目标对象和动态代理绑定起来。便于客户端调用。

    3、实现invoke 方法。

    JDK动态代理,只能代理实现接口的类。如果针对类来实现代理,则需要cglib 代理了。


    代理模式的本质:控制对象访问

  • 相关阅读:
    期末考试冬眠
    题解 P1457 【城堡 The Castle】
    题解 P1052 【过河】
    题解 P5663 【加工零件【民间数据】】
    与 macOS 10.12 兼容的OpenCV版本
    summarise() regrouping output 警告
    binary_crossentropy和BinaryCrossentropy的区别
    损失函数BinaryCrossentropy例子说明
    理解功能强大的sed替换命令
    理解GAN对抗神经网络的损失函数和训练过程
  • 原文地址:https://www.cnblogs.com/pan2011/p/3857404.html
Copyright © 2020-2023  润新知