软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> SpringAOP实现过程的总结 -> 正文阅读

[架构设计]SpringAOP实现过程的总结


 通过阅读SpringAOP源码,根据自己对源码的的理解,总结了Spring AOP是如何实现切面编程的。下面是根据自己理解画的流程图。


[img]http://img.blog.csdn.net/20160329134537314

 
     用户通过配置XML <aop:aspectj-autoproxy>或@EnableAspectJAutoProxy注解来开启AOP自动代理对象,spring IOC容器在启动时会将配置的目标对象bean、切面及相关通知信息,解析成Advisor对象对应的BeanDefintion,并把代理对象的配置信息保存在ProxyConfig对象中。AbstractAutoProxyCreator继承了ProxyConfig,且实现了SmartInstantiationAwareBeanPostProcessor , BeanFactoryAware接口,这意味着当IOC容器启动时,会创建AbstractAutoProxyCreator对象,实现了BeanFactoryAware意味着,在AbstractAutoProxyCreator实例初始化阶段,BeanFactory自动注入DefaultListableBeanFactory工厂给AbstractAutoProxyCreator实例使用,有BeanFactory对象则可以通过getBean方法来访问容器中所有的通知对象Advisor相关信息.每当调用BeanFactory取得bean对象时,利用实现了SmartInstantiationAwareBeanPostProcessor的后置处理器功能,BeanFactory会在多个阶段自动调用AbstractAutoProxyCreator这个后置处理器的实现方法,这些实现方法用来判断该Bean是否需要代理,判断Bean是否需要的代理的依据是根据该bean对象是否在IOC容器中存在匹配的一个或多个通知Advisor对象,存在则需要代理,否则,就放过。

      根据bean对象的信息,从工厂中查询匹配的一个或多个通知Advisor对象,工厂通过Advisor.class类型查询到所有的Advisor类型,然后使用bean的class类型与Advisor对应的目标类型匹配,匹配成功的就取得该通知对象形成集合,并包装成Advisor接口对象集合。
   
      AdvisedSupport从用户定义的信息中取得包含了所有关于目标对象的信息和设置,还包括通知器拦截器等,这个对象是生成AOP代理方法的输入参数。代理工厂ProxyFactory继承了AdvisedSupport拥有了代理需要的配置,调用getProxy方法来得到代理对象Object。getProxy方法实现是根据bean的信息不同进行不同的代理方式:JDK代理或CGLIB代理。
      JDK代理对象和CGLIB代理对象,如果没有设置指定代理目标类,AOP自动识别进行代理,目标对象是接口类则使用JDK代理,否则就使用CGLIB代理。
      JDK中所要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中具有一定的局限性,而且使用反射的效率也并不是很高.
  使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。
    JDK代理三要素Proxy.newProxyInstance(类加载器,目标接口,InvocationHandler实现),JDKDynaimicAopProxy实现了InvocationHandler接口,并使用了AdvisedSupport中存在的目标接口,及设置的类加载器,进行JDK的动态代理。
    CGLIB创建代理主要是创建Enhancer enhancer,并通过AdvisedSupport设置相应的属性,比如目标类rootClass,如果由接口合并接口给代理类,最主要的是设置Callback集合和CallbackFilter,使用CallBackFilter可以根据方法的不同使用不同的Callback进行拦截和增强方法。其中最主要的使用于AOP的Callback是DynamicAdvisedInterceptor。
    代理完成后,在从IOC容器中访问该对象时,返回的将是一个代理对象。当调用该对象的方法时,则根据不同的代理,调用的代理方法也不同。
    使用JDK动态代理的回调方法是
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
     使用CGLIB代理对象的回调方法是
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
        通过一系列的准备,已经为实现AOP的横切机奠定了基础,在这个基础上,AOP的Advisor已经可以通过AOPProxy代理对象的拦截机制,对需要它进行增强的target目标对象发挥切面的强大威力。
       可以把AOP的实现部分堪称有基础设施准备和AOP运行辅助这两部分组成,这里的AOPProxy代理对象的生成,可以看作是一个静态的AOP基础设施的建立过程。通过这个准备过程,把代理对象、拦截器这些待调用的部分都准备好,等待着AOP运行过程中对这些基础设施的使用。对于应用触发的AOP应用,会涉及AOP框架的运行和对AOP基础设施的使用。这些动态的运行部分,是从拦截器回调入口开始的。
      拦截器回调入口在JDK的invoke方法和CGLIB的 intercept方法中,当代理对象的方法被调用时,会触发相应的invoke方法或intercept方法,根据目标对象查询相应的拦截器链,如果不存在拦截器链直接调用目标对象的方法。否则就开始拦截器链的调用。JDK代理和CGLIB最终会殊途同归,它们对拦截器链的调用都是在ReflectiveMethodInvocation类中通过proceed方法实现的。ReflectiveMethodInvocation类实现了AOP 联盟定义方法拦截接口MethodInvocation,其中该接口中proceed()方法会逐个运行拦截器的拦截方法。ponitCut动态方法匹配成功的拦截器则进行方法的调用,这里使用了责任链的模式,主要代码这段interceptor.invoke(this);
      想一想自行车上的链子,一节链子连接另一节链子,当一节链子被齿轮带动,则这节链子会带动另一节链子。invoken方法是齿轮,interceptor和this都是MethodInterceptor的实例,相当于this是当前一节链,interceptor是后一节链,齿轮转动时,后一节链条需要当前的链条带动。就像当于interceptor.invoke(this); 而这里是拦截器链,是一个集合。相当于有多个的链条连接着。这样一链调用另一链循环着直到链条结束,当然现实的链条不能断,不然自行车就没法骑了。
      这些链条是如何形成的呢? 链条里是包含什么?invoke方法里处理什么呢?
        一个拦截器链需要实现MethodInterceptor接口,并实现Object invoke(MethodInvocation invocation)方法,在invoke方法中,如果需要下一个链条或得到前一个链条结果,则需要调用方法参数MethodInvocation的proceed()方法,进行下一个链条,默认进入ReflectiveMethodInvocation进行处理。
      Spring定义三个MethodInterceptor实现,分别为MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor
分别为目标方法调用前进行前置通知拦截器,目标方法调用后进行后置通知拦截器,及目标对象出现异常进行异常通知拦截器,在方法invoke中,会调用通知的方法,通知的方法是用户定义的业务逻辑。因此MethodInterceptor需要通知对象Advisor,从Advisor中取得通知Advice。不同的方法拦截器需要的不同的通知对象,后置拦截器需要后置通知,前置拦截器需要前置通知,而异常拦截器需要异常通知,这里就需要把通知适配成拦截器。
       这些通知存在AdvisedSupport中,从AdvisedSupport对象中取得所有Advisor,Spring使用了适配器模式,取得这些Advisor包含的通知对象,根据通知对象的类型,适配成相应的拦截器,适配完的拦截器就形成了拦截器链。
      当ReflectiveMethodInvocation中interceptor.invoke(this);就会进行拦截器链的调用,调用的实际是通知方法即用户的业务逻辑,调用的前后根据invoke()方法中,业务逻辑在调用proceed()方法前还是后来决定。
下面引用:Spring技术内幕--深入解析Spring架构与设计原理
      在Spring的平台功能中,AOP是一个核心模块,通过对AOP的使用,极大地丰富了Spring框架地功能,比如在各种驱动组件的实现上,很灵活地运用了AOP的功能特性。
      在Spring AOP的基础实现中,可以了解Spring如何得到AOPProxy代理对象,一即如何利用AOPProxy代理对象来对拦截器进行处理。Proxy代理对象的使用,在SpringAOP的实现过程中是非常重要的一个部分,Spring AOP充分利用了像Java的Proxy、反射技术以及第三方字节码技术实现CGLIB这些技术方案,通过这些技术,完成了AOP需要的AopProxy代理对象的生成。回顾通过ProxyFactoryBean实现AOP的整个过程,可以看到,在它的实现中,首先需要对目标对象以及拦截器进行正确配置,以便AopProxy代理对象顺利产生;这些配置既可以通过配置ProxyFactoryBean的属性来完成,也可以通过编程式地使用ProxyFactory来实现,这两种AOP地使用方式只是在表面配置地方式上不同,对于内在地AOP实现原理它们是一样地。在生成AopProxy代理对象地时候,Spring AOP设计了专门的AopProxyFactory作为AopProxy代理对象的生产工厂,由它来负责产生相应的AopProxy代理对象,在使用ProxyFactoryBean得到AopProxy代理对象的时候,默认使用的AopProxy代理对象的生产工厂是DefaultAopProxyFactory对象。这个对象是AopProxy生产过程中一个比较重要的类,它定义了AopProxy代理对象的生成策略,从而决定使用那种AopProxy代理对象的生成技术(是使用JDK的动态代理还是CGLIB)来完成生产任务。而最终的AOPProxy代理对象的产生,则交给了JdkDynamicAopProxy和Cglib2AopProxy这两个具体的工厂来完成,它们使用了不同的生产技术。
      在得到AopProxy代理对象后,在代理的接口方法被调用执行的时候,也就是当AopProxy暴露代理的方法被调用的时候,前面定义的Proxy机制就起作用了。当Proxy对象暴露的方法被调用时,并不是直接运行目标对象的调用方法,而是根据Proxy的定义,改变原有的目标对象方法调用的运行轨迹。这种改变体现在,首先会触发对这些方法调用进行拦截,这些拦截为目标调用的功能增强提供了工作空间。拦截过程在JDK的Proxy代理对象中,是通过invoke方法来完成的,这个invoke方法是虚拟机触发的一个回调;而在CGLIB的Proxy代理对象中,拦截是由设置好的回调callback方法来完成。有了这些拦截器的拦截作用,才会有AOP切面增强大显身手的舞台。

     

      具体来说,在ProxyFactoryBean的回调中,首先会根据配置来对拦截器是否与当前的调用方法相匹配进行判断。如果当前的调用方法与配置的拦截器相匹配,那么相应的拦截器就会开始发挥作用。这个过程是一个遍历的过程,它会遍历在Proxy代理对象中设置的拦截器链中的所有拦截器。经过这个过程后,在代理对象中定义好的拦截器链中的拦截器会被逐一调用,直到整个拦截器的调用完成位置。在对拦截器的调用完成以后,才是对目标对象的方法调用。这样,一个普通的Java对象的功能就得到了增强,这种增强和现有的目标对象的设计是正交解耦的,这也是AOP需要达到的一个目标。

      在拦截器的调用过程中,实际上已经封装了Spring对AOP的实现,比如对各种通知器的增强织入功能。尽管在使用SpringAOP的时候,看到的是一些Advice的使用,但实际上这些AOP应用中接触到的Advice通知是不能直接对目标对象完成增强的。为了完成AOP应用需要的对目标对象的增强,Spring AOP做了许多工作,对应于每种Advice通知,Spring设计了对应的AdviceAdapter通知适配器,这些通知适配器实现了advice通知对目标对象不同增强方式。对于这些AdviceAdapter通知适配器,在AopProxy代理对象的回调方法中,需要由一个注册机制,它们才能发挥作用。完成这个注册过程之后,在拦截器链中运行的拦截器已经是经过这些AdviceAdapter适配过的拦截器了。有了这些拦截器,再去结合AopProxy代理对象的拦截回调机制,才能够让advice通知对目标对象的增强作用是时在在地发生。“谁知盘中餐,粒粒皆辛苦”。
看起来简洁易用地AOP,和IOC容器地实现一样,背后同样蕴含这许多艰辛的努力。

......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-03-29 23:00:06  
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-17 15:01:21
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --