Spring框架(四)AOP之代理模式

来源:互联网 发布:淘宝直通车黑车技术 编辑:程序博客网 时间:2024/06/05 16:40

本篇介绍一下Spring的AOP模块中关于面向切面的概念。AOP全称Aspect  Oriented Programming,即面向切面编程。第一次听说面向切面编程可能会比较陌生,或者心里堵得慌。这到底是个什么鬼。但是,不要紧,我们不要太去抠字眼,想通过这几个字就想搞明白什么是面向切面,是不太可能的。所以,先不管什么是面向切面,先把这个概念抛掷脑后。先看看下面这个例子:

我有个朋友,自己在家做点蛋糕,然后通过朋友圈卖。送货都是他自己亲自送货。模型如下图:


后来发现这样亲自送货,根本赚不到钱,而且时间都耗费在车上了,因此没有时间去做蛋糕了。这样导致,做得少不敢接太多单,利润都给城市交通了,根本赚不到钱。要解决问题,就需要找一个快递公司专门送货。如是,就有了如下模型了:


看到这里,可能有人会发现,这不就是代理模式吗。确实,这就是代理模式,将原来自己做的事情,交给代理(快递公司)来做,省时省力省钱。

那这代理模式跟AOP有什么关系?代理模式就是AOP的核心原理。面向切面编程可以简单说是面向代理模式编程。所以搞明白什么事代理模式,基本就清楚面向切面是怎么回事了:


接下来,我们通过代码的形式来实现上面的案例:

1、卖家Seller类:

package com.androidxx.proxy;/** * 卖家 * @author yangjw * */public class Seller {/** * 卖蛋糕 */public void sell() {System.out.println("做蛋糕");}}


2、快递代理ExpressProxy类:

package com.androidxx.proxy;public class ExpressProxy {Seller seller = new Seller();public void transport() {System.out.println("上门收快递");seller.sell();System.out.println("快递送达");}}


3、买家Buyer类:

package com.androidxx.proxy;/** * 买家 * @author yangjw */public class Buyer {ExpressProxy express = new ExpressProxy();public void buy() {express.transport();}}


4、测试类:

package com.androidxx.proxy;import static org.junit.Assert.*;import org.junit.Test;public class BuyerTest {@Testpublic void test() {Buyer buyer = new Buyer();buyer.buy();}}

以上就是一个静态代理的例子,代理模式就是由一个人代表另一个人完成一项任务。以上例子中就是由快递(ExpressProxy)代表卖家(Seller)去送货给买家(Buyer)。但是,看上面的例子,ExpressProxy为了代理Seller,需要在ExpressProxy类中创建一个Seller对象(被代理的对象);在现实生活中,一个快递公司往往都是可以给任何公司或者组织或者个人送快递的,也就是说现实生活中的快递公司可以是所有人或者组织的代理者。那这样我们岂不是要在ExpressProxy类中创建成千上万个被代理的对象?当然不需要,于是Java推出的动态代理的概念。动态代理就是可以在不修改代理类(ExpressProxy)的情况下,可以给所有对象进行代理。


动态代理

实现动态代理需要了解2个类,分别是InvocationHandler和Proxy,其中InvocationHandler是一个接口,是代理需要实现的接口;Proxy是帮助产生代理实例的一个类。接下来,使用动态代理优化以上案例中的代理模式。

1、首先要定义一个接口SuperSeller:

package com.androidxx.proxy;public interface SuperSeller {public void sell();}

2、创建Seller类,并实现SuperSeller接口:

package com.androidxx.proxy;/** * 卖家 * @author yangjw * */public class Seller implements SuperSeller {/** * 卖蛋糕 */public void sell() {System.out.println("做蛋糕");}}

3、创建动态代理类:

package com.androidxx.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class DynamicExpressProxy implements InvocationHandler{private Object seller;public DynamicExpressProxy(Object seller) {super();this.seller = seller;}/** * 参数1:proxy是代理类的一个对象,但是并不是指代当前的DynamicExpressProxy对象。 * 参数2:需要执行的被代理对象的方法 * 参数3:需要执行方法的参数 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("上门收快递");//反射原理,执行方法//Obj是method方法的返回值Object obj = method.invoke(this.seller, args);System.out.println("送达快递");return obj;}}


4、买家类Buyer:

package com.androidxx.proxy;import java.lang.reflect.Proxy;/** * 买家 * @author yangjw */public class Buyer {public void buy() {//被代理的对象Object obj = new Seller();//被代理对象的Class对象Class clss = obj.getClass();//通过Proxy产生代理类的实例,此处的proxy对象是代理。//动态代理的关键就是此句,动态的创建代理类对象SuperSeller proxy = (SuperSeller) Proxy.newProxyInstance(clss.getClassLoader(), clss.getInterfaces(), new DynamicExpressProxy(obj));//通过代理执行sell方法proxy.sell();}}

5、测试类:

package com.androidxx.proxy;import static org.junit.Assert.*;import java.lang.reflect.Proxy;import org.junit.Test;public class BuyerTest {@Testpublic void test() {Buyer buyer = new Buyer();buyer.buy();}}

以上就是使用动态代理的方式来处理卖家--快递--买家的关系。动态代理,顾名思义就是动态的去创建代理。如上代码中Proxy.newProxyInstance就是用于动态创建代理的方法。关于动态代理中的InvocationHandler和Proxy其实很简单,InvocationHandler用于定义一个动态代理的类,Proxy用于产生代理类的实例。

说了半天的代理模式,它跟AOP面向切面有什么关系呢?在开头的时候,已经说了,AOP的核心其实就是代理模式。明白代理模式,在接下来的AOP学习过程中,就容易理解了。大家在学习AOP的时候,其实可以理解为在学习动态代理模式。


Spring 的AOP其实就是一种动态代理模式的实现。


此篇博客为了尽量简化代理模式的说明,有些概念写的可能比较简单,也是为了便于去理解。如果有错误的地方,也欢迎指正。




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 棉拖鞋洗了发黄怎么办 小狗5天不吃东西怎么办 手上猴子总是不停的起怎么办 真空压缩袋破了怎么办 兔子突然腿瘸了怎么办 被宠物兔咬出血怎么办 小兔子不吃东西精神不好怎么办 小狗脐带咬开了怎么办 刚生的狗就死了怎么办? 兔子生了不喂奶怎么办 兔子出生4天摸了怎么办 兔子吃了纸箱子怎么办 被小兔子抓一下怎么办 兔子吃了蟑螂药怎么办 兔子洗了澡要死怎么办 养的花蔫了怎么办 养的小鸡很大了怎么办 养的小兔子死了怎么办 小狗出现爬跨行为怎么办 养的小狗总做吞咬人的行为怎么办 螃蟹和柿子一起吃了怎么办 指甲上月牙没了怎么办 手指上月牙没了怎么办 指甲上没半月牙怎么办 电动车车牌被偷了怎么办 警察拖车拖坏了怎么办 6岁儿童牙疼怎么办 小白单车不退押金怎么办 光盘放笔记本电脑里读不出来怎么办 cd光盘读不出来怎么办 最近脸干的不行怎么办 脸感觉干的不行怎么办 新生儿睡觉黑白颠倒了怎么办 婴儿吐水和奶花怎么办 刚刚出生的宝宝拉肚子怎么办 刚出生的婴儿拉肚子怎么办 新生儿5天拉稀水怎么办 10个月孩子拉肚子怎么办 不满月的宝宝拉肚子怎么办 一周岁宝宝发烧腹泻呕吐怎么办 6个月宝宝37度怎么办