spring aop 总结和疑点释义

1.png

AspectJ介绍:AspectJ是一个java实现的AOP框架,它能够对java代码进行AOP编译(一般在编译期进行),让java代码具有AspectJ的AOP功能(当然需要特殊的编译器)
AspectJ的织入方式及其原理概要:我们仍需要了解AspectJ应用到java代码的过程(这个过程称为织入),对于织入这个概念,可以简单理解为aspect(切面)应用到目标函数(类)的过程。对于这个过程,一般分为动态织入和静态织入,动态织入的方式是在运行时动态将要增强的代码织入到目标类中,这样往往是通过动态代理技术完成的,如Java JDK的动态代理(Proxy,底层通过反射实现)或者CGLIB的动态代理(底层通过继承实现),Spring AOP采用的就是基于运行时增强的代理技术,这点后面会分析,这里主要重点分析一下静态织入,ApectJ采用的就是静态织入的方式。ApectJ主要采用的是编译期织入,在这个期间使用AspectJ的acj编译器(类似javac)把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类(即编译后的字节码包含了aspect代码)
ApectJ编译方式:当然除了编译期织入,还存在链接期(编译后)织入,即将aspect类和java目标类同时编译成字节码文件后,再进行织入处理,这种方式比较有助于已编译好的第三方jar和Class文件进行织入操作

spring aop和aspectj的关系:spring aop 更关注于与ioc的结合,底层采用动态编译即jdk动态代理和cglib,并按照aspectj风格进行aop的开发(比如设置apsectj注解,定义pointcut advice advisor等)

InstantiationAwareBeanPostProcessor 在BeanPostProcessor基础上增加 实例化前后的扩展点(BeanPostProcessor是在bean初始化前后进行操作)

AspectJ的逻辑

1.在初始化之后开始调用,就是解析某个类是否需要变成代理
2.判断是否需要代理的原则,找到这个类是否有对应的advisor,如果有就是需要变成代理
3.如何去寻找advisor,针对于asepctJ是去寻找对应的@AsepctJ的注解类,然后获取所有的adviosr 然后解析advisor上面的pointcut,看看ponitcut是否匹配目前的类或者方法
4.当存在advisor之后在advisor集合里面第一位添加ExposeInvocationInterceptor,该类是作为调用链的头部 可以方便的获取调用链上下文
5.不论是jdk还是cglib调用的都是ReflectiveMethodInvocation的process方法,即spring把advisor转换成MethodInterceptor
该方法内部就是循环调用MethodInterceptor,当调用链结束了才调用 真正方法
整个逻辑类似递归调用。
6.依靠proxyfactory创建代理对象
@Asepctj的aop生成源码解析:https://www.jianshu.com/p/58e0828c062c

ProxyFactoryBean的逻辑

和proxyfactoryBean的aop源码解析:https://www.jianshu.com/p/e376014e6795


之所以在源码中创建代理采用proxyFactory 而不是AspectJrpoxyFactory是因为这是父类 如果AspectJrpoxyFactory,会导致不适配其他类型,而且proxyfactory 有通用性,因为他们创建aopproxy的方法都是一样 只是收集advice不一样,而advice已经被收集到了


代理中遇到调用返回this方法会直接退换成proxy本身

cglib在创建proxy过程通过proxyfilter,来分配某些方法对应哪个callback,然后运行的执行哪个callback的intercept方法(不同的interceptor方法就是不同的callback方法的具体逻辑执行者)

springAop的更简单的总结:收集advisor 创建代理对象 把adviosr 转换成methodinterceptor 最终通过ReflectiveMethodInvocation(jdk)或者CglibMethodInvocation(其继承了ReflectiveMethodInvocation cglib)去执行这些interceptor,
ReflectiveMethodInvocation 逻辑:当我们只想对应的Interceptor要执行的内容,如果我们还需要只想下一步,就调用this.process,就又回到这个ReflectiveMethodInvocation的process方法


CGLIB:是在proxyproxy创建的时候进行method的intercept的分配和缓存
JDK:jdk 是在proxy第一次调用方法的进行method的intercept的分配和缓存


CglibMethodInvocation改写ReflectiveMethodInvocation的invokeJoinpoint方法,与使用反射相比,性能略有改善在调用公共方法时调用目标。(即JDK是通过method的invoke方法 而cglib通过MethodProxy的invoke)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 12,356评论 6 86
  • 我们的程序从编写到执行,单个模块一般都是从上到下、垂直、连续的。AOP是一种“横切”技术,能够在合适的地方“拦腰截...
    消失er阅读 2,040评论 0 5
  • 你曾出现在我的梦里,在梦里我看到了另一个你。在我眼里出现了你的倒影。 小毅是生活中大大咧咧没有教条的散漫性格...
    Zboomboomboom阅读 219评论 0 1
  • 电影 《教父》 小说 《三国演义》 体重 52kg Thinking In Java 类型信息 泛型 数组 容器
    Luna_Lu阅读 205评论 0 0
  • 作为一名“懒癌”,我觉得啃甘蔗是一件十分不便利的事情,比如不小心咬到自己、吃多易上火、咬来咬去让嘴巴发酸等等原...
    邓迟迟阅读 814评论 0 5