zoukankan      html  css  js  c++  java
  • 反射的应用之动态代理

    动态代理的使用,反射是动态语言的关键

    TestDynamicProxy

    package com.aff.dynamic;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /*
     动态代理是指客户通过代理类来调用其它对象的方法,
     并且是在程序运行时根据需要动态创建目标类的代理对象。
     动态代理使用场合:
                                调试
                                远程方法调用
    代理设计模式的原理: 
                       使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 
                       任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上。
     */
    
    
    //动态代理的使用,反射是动态语言的关键
    interface Subject {
        void action();
    }
    
    // 被代理类
    class RealSubject implements Subject {
        public void action() {
            System.out.println("我是被代理类,记得要执行");
        }
    }
    
    //代理类
    class MyInvocationHandler implements InvocationHandler {
        Object obj;// 实现了接口的 被代理类的 对象的声明
        //                 ①给被代理类的对象实例化
        //                 ②返回一个代理类的对象
    
        public Object blind(Object obj) {
            this.obj = obj;
            // Proxy:代理类
            // Proxy.newProxyInstance :new一个代理类的实例,也要实现 对应被代理类的 实现接口里的抽象方法
            // obj.getClass().getClassLoader(): 和obj的类加载器是一样的,obj是和被代理类的对象类加载器相同的
            // obj.getClass().getInterfaces(); 被代理类实现的什么接口, 代理类(Proxy)也一样
            // this : 实现了InvocationHandler接口的类对象,也就是MyInvocationHandler
            // 这一步真正的返回一个代理类的对象
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
        }
    
        // 每当代理类的对象调用 被重写的action方法时,就会被转化为对如下invoke方法的调用
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable {
            //returnVal  返回值相当于被代理类的抽象方法(action)的返回值
            Object returnVal = method.invoke(obj, args);//obj 被代理类的
            return returnVal;
        }
    }
    
    public class TestDynamicProxy {
        public static void main(String[] args) {
            //1.被代理类的对象
            RealSubject real= new RealSubject();
            //2.创建一个实现 InvocationHandler接口的类对象
            MyInvocationHandler handler = new MyInvocationHandler();
            //3.调用blind()方法,动态的返回一个同样实现了real所在类 实现的接口 的代理的对象
             Object obj = handler.blind(real);//real 是Subject类型,用Object来接收
             Subject sub = (Subject)obj;//得强转一下再调用action,此时的sub 就是代理类的对象、
             
             sub.action();//转到对 InvocationHandler接口的实现类(MyInvocationHandler)的invoke()方法的调用
        }
    }
    All that work will definitely pay off
  • 相关阅读:
    JAVA NIO 结合多线程
    ios即时通讯客户端开发之-mac上安装MySQL
    使用第三方库AFNetworking时遇到的问题
    用CocoaPods做iOS程序的依赖管理(转载)
    IOS8 设置TableView Separatorinset 分割线从边框顶端开始
    (转)UIViewController中各方法调用顺序及功能详解
    iOS中遍历数组的几种方法
    取消tableView上面多出来20个像素
    UIView动画中的一些坑
    ios build时,Undefined symbols for architecture xxx问题的总结(转)
  • 原文地址:https://www.cnblogs.com/afangfang/p/12625808.html
Copyright © 2011-2022 走看看