• 静态代理和动态代理


    所谓代理,可以认为是 客户无法直接与服务端交流,那么就需要一个媒介来处理他们之间的会面。思想比较简单,但是遇到真实情况下,静态代理比较容易理解,动态代理值得学习,想起以前别人的一些程序还是比较容易理解。

    一)静态代理

    1:

    public abstract class Subject
    {
        public abstract void request();
    }

    2:

    public class RealSubject extends Subject
    {
        public void request()
        {
            System.out.println("From real subject.");
        }
    }
    :

    3:

    public class ProxySubject extends Subject
    {
        private RealSubject realSubject; //代理角色内部引用了真实角色
        
        public void request()
        {
            this.preRequest(); //在真实角色操作之前所附加的操作
            
            if(null == realSubject)
            {
                realSubject = new RealSubject();
            }
            
            realSubject.request(); //真实角色所完成的事情
            
            this.postRequest(); //在真实角色操作之后所附加的操作
        }
        private void preRequest()
        {
            System.out.println("pre request");
        }
        
        private void postRequest()
        {
            System.out.println("post request");
        }
    }

    4:

    public class Client
    {
        public static void main(String[] args)
        {
            Subject subject = new ProxySubject();
            
            subject.request();
        }
    }
    二)动态代理

    1:

    public interface Subject
    {
        public void request();
    }


    2:

    public class RealSubject implements Subject
    {
        public void request()
        {
            System.out.println("From real subject!");
        }

    }

    3:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;

    /**
     * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象
     * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要
     * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后
     * 加入自己的一些额外方法。
     *
     */

    public class DynamicSubject implements InvocationHandler
    {
        private Object sub;
        
        public DynamicSubject(Object obj)
        {
            this.sub = obj;
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable
        {
            System.out.println("before calling: " + method);
            
            method.invoke(sub, args);
            
            System.out.println(args == null);
            
            System.out.println("after calling: " + method);
            
            return null;
        }
        

    }

    4:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.List;
    import java.util.Vector;

    public class VectorProxy implements InvocationHandler
    {
        private Object proxyObj;

        public VectorProxy(Object obj)
        {
            this.proxyObj = obj;
        }

        public static Object factory(Object obj)
        {
            Class<?> classType = obj.getClass();

            return Proxy.newProxyInstance(classType.getClassLoader(),
                    classType.getInterfaces(), new VectorProxy(obj));
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable
        {
            System.out.println("before calling: " + method);
            
            if(null != args)
            {
                for(Object obj : args)
                {
                    System.out.println(obj);
                }
            }
            
            Object object = method.invoke(proxyObj, args);
            
            System.out.println("after calling: " + method);
            
            return object;
        }
        
        public static void main(String[] args)
        {
            List v = (List)factory(new Vector());
            
            System.out.println(v.getClass().getName());
            
            v.add("New");
            v.add("York");
            
            System.out.println(v);
            
            v.remove(0);
            System.out.println(v);
            
        }

    }

    5:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;

    public class Client
    {
        public static void main(String[] args)
        {
            RealSubject realSubject = new RealSubject();

            InvocationHandler handler = new DynamicSubject(realSubject);

            Class<?> classType = handler.getClass();

            // 下面的代码一次性生成代理

            Subject subject = (Subject) Proxy.newProxyInstance(classType
                    .getClassLoader(), realSubject.getClass().getInterfaces(),
                    handler);

            subject.request();

            System.out.println(subject.getClass());

        }

    }

    Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。

    其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。可以这样想象:编译期间我们不知道有多少类,只有在运行期间利用反射机制动态的生成一些class。这就是所谓的动态代理,表面做到了灵活性,但是我始终觉得比较耗资源。


  • 相关阅读:
    js点击按钮为元素随机字体颜色和背景色
    js随即数字random实现div点击更换背景色
    while循环计算1-100和,1-100内偶数/奇数/被整除的数的和
    慕课手机展示页案例
    第3题:求子数组的最大和
    第4题:在二叉树中找出和为某一值的所有路径
    第5题:查找最小的K个元素
    Linux系统开启IPv6任播(anycast)地址
    第7题:判断两个链表是否相交
    第8题上:思维题
  • 原文地址:https://www.cnblogs.com/MedivhQ/p/3801440.html
Copyright © 2020-2023  润新知