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其实就是一种动态代理模式的实现。
此篇博客为了尽量简化代理模式的说明,有些概念写的可能比较简单,也是为了便于去理解。如果有错误的地方,也欢迎指正。
- Spring框架(四)AOP之代理模式
- Spring AOP之代理模式
- Spring aop之代理模式
- Spring框架学习之(四)--AOP
- spring框架详解(四)--AOP代理
- (九)Spring核心框架 - AOP之动态代理机制
- 代理模式之spring的AOP
- spring-aop入门之静态代理模式
- spring-aop入门之动态代理模式
- Spring AOP代理模式
- Spring AOP 代理模式
- Spring学习框架之四(AOP)
- 代理模式(proxy)和spring AOP
- Spring框架中的AOP思想 动态代理模式
- Spring框架中的AOP思想 动态代理模式
- Spring 框架学习(四):AOP
- SSH框架之Spring的代理模式
- Spring AOP中的代理模式
- 67. Add Binary
- 注册Tomcat为系统服务
- 求在IOS上扫描PDF417的免费插件
- 关于NRV优化详细分析
- ExploitExercises_Nebula_Level12
- Spring框架(四)AOP之代理模式
- Docker部署 elasticsearch 2.X 简要步骤概述
- java的动态代理机制详解
- Ajax post请求跳转页面
- 获取屏幕的宽高
- Google Map Api 谷歌地图接口整理
- 提高Unity中C#代码质量的22条准则
- Spark错误异常-资源占用,任务挂起
- 第一次使用git提交失败的解决方法