美文网首页
Spring-AOP_03-动态代理-JDK动态代理

Spring-AOP_03-动态代理-JDK动态代理

作者: rock_fish | 来源:发表于2018-06-08 16:07 被阅读0次
    JDK动态代理是这样一种Class:
    • 在运行时生成class,
    • 在生成他时,必须提供一组interfaces给它,然后该class就会声明它实现了这些interfaces.因此我们可以将该class的实例当做这些interfaces中的任何一个来用.
    • 当然这个动态代理其实就是一个Proxy,它不会代替你做实质性的工作,在生成他的实例时,你必须提供一个handler,由它接管实际的工作.
    个人感觉这么去理解JDK动态代理:
    • 1.按照什么规则,提供一个什么
    • 2.替,具体做什么事.

    映射一下

    1.类加载器按照给定的接口规则,提供(创建)了一个代理类.
    2.替目标类(被代理的类),具体做InvocationHandler实现的逻辑.


    JDK动态代理 只能代理接口,核心代码理解:

    1.类加载器按照给定的接口规则,提供(创建)了一个代理类.

    //返回代理类的一个实例,返回后的代理类可以当做被代理类使用
    static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
    

    loader:类加载器,用于创建代理类实例
    interfaces:实现的接口,标识代理类实现了哪些接口
    invocationHandler:实际代理内容的实现.

    2.替目标类(被代理的类),具体做InvocationHandler实现的逻辑.

    //InvocationHandler 类中的方法
    public Object invoke(Object obj,Method method,Object[] args)
    

    obj: 一般指代理对象 代理对象已经被创建了,传递到这里,
    method:被代理的方法,指定的接口中的方法
    args:该方法的参数数组.实际方法调用时候的实际参数数组

    上述两个方法位于java.lang.reflect包下,从包名看出属于反射的范畴.


    public interface Subject {
        public void request();
    }
    
    public class RealSubject implements Subject {
        public void request() {
            System.out.println("From real subject");
        }
    }
    
    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 {
            //proxy 是代理对象,不是真实对象.
            System.out.println("before calling: " + method);
            //这里使用的sub是被代理的对象的实例.
            method.invoke(sub,args);//sub:对象(对应到面向对象中实例方法中的this) args:方法参数(对应到类中的实例方法运行时参数)
            System.out.println(args == null);
            System.out.println("after calling: " + method);
            return null;
        }
    }
    
    //JDK动态代理实现步骤
    //1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
    //2.创建被代理的类以及接口(类实现此接口)因为JDK动态代理的规则,必须有接口
    //3.通过Proxy的静态方法 newProxyInstance()创建一个代理
    //4.通过代理调用方法.
    public class TestProxy {
        public static void main(String[] args) {
            RealSubject realSubject = new RealSubject();
    
            InvocationHandler handler = new DynamicSubject(realSubject);
            Class<?> classType = handler.getClass();
            Class<?>[] interfaces = realSubject.getClass().getInterfaces();
            Subject subject = (Subject) Proxy.newProxyInstance(classType.getClassLoader(),interfaces,handler);
            subject.request();
            System.out.println(subject.getClass());
        }
    }
    

    运行结果:

    before calling: public abstract void com.zto.learn.Subject.request()
    From real subject
    true
    after calling: public abstract void com.zto.learn.Subject.request()
    class com.sun.proxy.$Proxy0
    
    

    通过这种方式,被代理的对象(RealSubject)可以在运行时动态概念,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也 可以动态改变,从而实现了非常灵活的动态代理关系.

    一篇不错的文章:http://www.cnblogs.com/xujian2014/p/4843888.html

    相关文章

      网友评论

          本文标题:Spring-AOP_03-动态代理-JDK动态代理

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