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

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • title: Jdk动态代理原理解析 tags:代理 categories:笔记 date: 2017-06-14...
    行径行阅读 19,625评论 3 36
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,595评论 19 139
  • https://blog.csdn.net/luanlouis/article/details/24589193 ...
    小陈阿飞阅读 966评论 1 1
  • 这个社会上有一个雷打不动的定律是:一切供给过多的东西都会变得廉价。当然,你的善意也不能免俗。有的人,对任何人都友好...
    艾小墨阅读 511评论 1 1
  • 看了很多文章,最近在向小文艺的方向前进,不能说自己升华啦,只是年龄把我推到了这个台阶-初熟。没啥小野心,就想给自己...
    Sa小ra阅读 261评论 0 1

友情链接更多精彩内容