美文网首页程序员
Java静态代理和动态代理模式

Java静态代理和动态代理模式

作者: 临窗听雨 | 来源:发表于2017-12-26 22:42 被阅读22次

    简单介绍下静态代码和动态代理模式,以前面试被问到butterknife的原理,对这块也不太懂,今天我们一起了解下。
    对象接口:

    public interface Subject {
        void request();
    }
    

    真正需要被代理的对象实现这个接口:

    public class RealSubject implements Subject{
    
        public void request() {
            System.out.println("正真的角色");
        }
    }
    

    然后写一个代理对象:

    public class Proxy1 implements Subject{
    
        //代理对象需要持有一个被代理对象的引用
        private Subject subject;
        
        public Proxy1(Subject subject){
            this.subject = subject;
        }
        
        public void request() {
            System.out.println("begin");
            subject.request();
            System.out.println("end");
        }
    }
    

    代理对象需要持有一个被代理对象的引用,调用端调用代理对象的request方法,间接的就调用了被代理对象的request方法。

    public class Test {
     public static void main(String[] args) {
            RealSubject realSubject = new RealSubject();
            Proxy1 proxy = new Proxy1(realSubject);
                proxy.request();
        }
    }
    

    测试结果:


    静态代理测试.PNG

    动态代理,Java api提供了InvocationHandler这个类,用来反射执行被代理对象的方法
    示例代码如下:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class MyInvacationHandler implements InvocationHandler{
        
        /**
         * 真实对象类型
         */
        private Object target;
        
        public MyInvacationHandler(Object object){
            this.target = object;
        }
    
        /**
         * 调用invoke
         */
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("before");
            Object result = method.invoke(target, args);
            System.out.println("after");
            return result;
        }
    
    }
    

    调用端代码:

    import java.lang.reflect.Proxy;
    
    public class Test {
        public static void main(String[] args) {
            Subject subject = new RealSubject();
            MyInvacationHandler invacationHanlder = new MyInvacationHandler(subject);
            //代理对象
            Subject proxy = (Subject) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
                    subject.getClass().getInterfaces(), invacationHanlder);
            proxy.request();
            
        }
    }
    

    通过Java提供的Proxy.newProxyInstance方法实例化代理对象,然后通过代理对象执行被代理对象的request方法。
    测试结果:


    动态代理.PNG

    相关文章

      网友评论

        本文标题:Java静态代理和动态代理模式

        本文链接:https://www.haomeiwen.com/subject/fpzegxtx.html