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

2018-06-08  本文已影响0人  rock_fish
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

上一篇下一篇

猜你喜欢

热点阅读