Java动态代理

一,简介

在将动态代理之前,先按照我自己的理解来讲讲代理模式,和静态代理

二,代理模式

    我们常常说代理模式是一种java常见的设计模式,我们会误以为只有Java才有代理模式,其实不是。设计模式本身和语言没有任何的关联,它是一种设计思想,就好像你设计了一件衣服,我们强调的设计这个词,在这里其实是着重在款式和造型上,跟你之后用什么面料来实现这个设计是不同的概念。不管是代理模式,桥接模式,享元模式,适配器模式。。。都是站在设计的角度上来讲,用什么语言来完成这个设计都可以。    

    回过来讲代理模式,代理,代理,其实就是我们生活中常听到的,”您好,我是某某公司的,我们公司是做哪个品牌的销售代理的“,或者是你的微信朋友圈的广告,她们都会说自己是哪款护肤产品的代理,哪款内衣的代理。很明显她们并不是在实际的生产这些东西,她们只是在销售的环节上做了代理。所以我认为的代理模式就是中间人,你有什么需要跟中间人说,他回过头来不会自己帮你做这事,我会去找真正干事的人给你做。但是中间人代理不了他找的人都办不到的事,就好像我代理的明明是内衣,你却偏偏找我买护肤品,所以为什么说代理对象要有和被代理对象要实现共样的方法,是为了不能让代理打着旗号卖自己都拿不到的东西。

三,静态代理

    下面我模拟一个场景,通过Java来自己实现一个静态代理的代码。场景是这样的,有天公司的领导下来检查,到了工程部,工程部的员工不在公司都在工地上,但是工程部的经理在。领导就跟工程部经理说最近工期比较紧,希望大家努力工作,工程部经理当时二话没说就答应了(站着说话不腰疼),领导走了,工程部经理去工地找工人们集合,下达命令说,”小的们,工期紧,大家紧凑点干,到时候完工我请各位吃烧烤“,屁放完工程部经理就回家了,工人们就努力地干活,最后完成了项目。很明显代理对象(工程部经理)就是形式上努力工作,真正干活的是被代理对象(工人)。

1,代理对象和被代理对象要实现相同的接口

    我创建了一个接口Person,里面有努力工作的方法


Java动态代理_第1张图片
图一

2,创建被代理对象

    在我们上面说的场景中,被代理对象就是我们的工人,工人有自己姓名和年龄特征,同时要实现Person这个接口,来重写里面的harWorking方法


Java动态代理_第2张图片
图二

3,创建代理对象

    上述的场景中我们的代理对象就是工程部的经理,代理对象要做两件事,第一,为了跟被代理的对象方法保持一致,必须跟被代理对象实现同一个接口Person。第二,要在将被代理的对象传进来。


Java动态代理_第3张图片
图三

    我们要注意的有两点,第一,我们在代理对象的这个构造方法的参数中传入的是Person对象,这就让我们想到了多态(父类的引用指向子类对象(向上转型),方法重写,继承(或许说实现))。第二,重写代理对象的hardWoring方法中,我们是调用被代理对象的hardWoring的行为。

4,运行测试静态代理


Java动态代理_第4张图片
图四

四,动态代理

    最后我们来讲java的动态代理。所谓动态代理,就是在运行时创建代理的方式,上面是我们自己实现的静态代理,之所以说静态,是因为是我们自己定义的代理对象,在程序运行之前就已经编译完成。相比静态代理动态代理的好处在于,动态代理可以对代理类的方法做统一的处理,你如我们希望在每个函数调用时都有一个前置通知,当然静态代理可以做到,但是我们发现当方法多时,前置通知就会变得很多,对程序的设计来说是不可取的。下面我们来具体说说,在java中如何实现动态代理。

1,创建公共接口

    跟静态代理一样,要先创建代理对象和被代理对象公共的接口,在这里我加了一个introduce的方法,为了接下来演示每个方法在执行都有前置通知的输出。


Java动态代理_第5张图片
图五

2,创建被代理对象

    被代理对象跟静态代理一样,只是多了一个introdu的方法。


Java动态代理_第6张图片
图六

3,创建自己的InvocationHadler类

    在java的动态代理中,我们的代理对象并不是我们自己写的,我们是通过实现InvocationHandler接口和Proxy类来实现。所以在这里我们需要创建一个自己的InvocationHandler类,通过重写invoke方法来调用我们被代理对象的行为。


Java动态代理_第7张图片
图七

    需要注意的是,这里的target是我们的被代理对象,在构造是时候传入,在invoke中调用;

4,创建代理对象

    这里我们创建代理对象的方式如下


Java动态代理_第8张图片
图八

在这里我们通过实例化InvocationHandler和实例化代理对象得到了代理对象的实例,在这里我们不难看出,是被代理对象传给了IncocationHandler,再在实例化代理对象时告诉代理对象需要代理的是谁。运行结果如下:


Java动态代理_第9张图片
图九

通过动态代理实现了前置通知

你可能感兴趣的:(Java动态代理)