前言

本篇是spi的第四篇,本篇讲解的是spi中增加的AOP,还是和上一篇一样,我们先从大家熟悉的spring引出AOP.

AOP是老生常谈的话题了,思想都不会是一蹴而就的.比如架构设计从All in OneSOA也是一个逐步演进的过程,所以本篇也讲讲这个AOP的思想演进过程.

插播面试题

  • 你提到了dubbo中spi也增加了AOP,那你讲讲这用到了什么设计模式,dubbo又是如何做的.

直入主题

假如我们就以AOP最常用的场景事务来说,我们最初的做法是怎么样的?

简单做法

图片

这些代码存在的问题就很明显了,比如

  • 处理事务的代码大量重复

  • 根据责任分离思想,在业务方法中,只需要处理业务功能,不该处理事务.

优化代码我们第一个想到的是设计模式,那么我们进入如下的优化

装饰设计模式

图片


通过装饰设计模式,我们解决了上面遇到的两个问题,但是同时也引出了新的问题,在客户端我们暴露了真实的对象EmployeeServiceImpl,这样就很不安全,那么我们可不可以把真实对象隐藏起来,让使用者看不到呢?那么我们进一步优化

静态代理

通过这种方式,真实对象对使用者进行了一定的隐藏,但是又引出了新的问题

  • 如果需要代理的方法很多,则每一种都要处理.比如图中只处理了save方法,万一有很多方法,则需要处理很多次

  • 接口新增了方法后,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法(EmployeeServiceImplEmployeeServiceImplProxy都要改动),增加了代码的维护难度

  • 代理对象的某个接口只服务于某一种类型的对象,比如EmployeeServiceImplProxy是只给IEmployeeService接口服务的,假如我新增了一个IRoleService,又要搞一个RoleServiceImplProxy,增加了维护难度

鉴于以上问题,我们能否再优化一下呢?答案是可以的

动态代理

动态代理类是在程序运行期间由JVM通过反射等机制动态的生成的,所以不存在代理类的字节码文件.代理对象和真实对象的关系是在程序运行事情才确定的.

动态代理的方式和区别我们前面有讲过,这里就简单演示一下jdk动态代理

图片

这样,对于使用者来说,就无需再关心事务的逻辑.当然这个还需要getProxyObject获取动态代理对象是不是还是太麻烦,那如何不调用getProxyObject就无声无息的注入动态代理对象呢?可以观看之前的[dubbo源码解析-简单原理、与spring融合]

dubbo-spi-aop

看了这么多演进的过程,是不是还是没有看到dubbo源码的影子?因为dubbo在做spi的设计的时候,也是有一个演进和优化的过程的.我们来看看dubbo是怎么做的

图片

下面引用文档介绍

ExtensionLoader 在加载扩展点时,如果加载到的扩展点有拷贝构造函数,则判定为扩展点 Wrapper 类。

Wrapper类内容:


通过 Wrapper 类可以把所有扩展点公共逻辑移至 Wrapper 中。新加的 Wrapper 在所有的扩展点上添加了逻辑,有些类似 AOP,即 Wrapper 代理了扩展点。

看到这里可能发现,dubbo里面的spi增加的aop,其实就是装饰者设计模式.但是从上面的演进中我们发现,装饰者设计模式还是有很多弊端的,后面是逐步演进,最后到达动态代理.那dubbo又是如何处理这个弊端逐步演进的?

dubbo里面有个概念叫扩展点自适应,也就是给接口注入拓展点是一个Adaptive实例,直到方法执行时,才决定调用的是哪一个拓展点的实现.

敲黑板划重点-小技巧

既然本篇提到了spring的aop,那么这里插播一个小技巧,Spring的AOP增强方式一共有5种,分别为

图片

面试的时候也会问到5种增强方式,但是很多同学都是说,我每天都在加班,哪有时间记这些.但是其实如果你理解他的设计思想,那么就可以"理解性记忆",以后想忘都忘不掉.

图片

其实他这5种方式就是根据try-catch-finally的模型来设计的,只要你记住了这个设计的思想,自然不会忘记这5种方式,这也是我之前反复强调的,理解透原理和设计思想,很多东西都是一通百通的.

写在最后

关注肥朝公众号,后续还会有更多奇巧淫技,真实企业场景源码级实战和大家分享.让"原理"不再只是面试装逼.也欢迎大家留言一起交流精进


更多相关文章

  1. 在python中执行shell命令的6种方法
  2. 多线程学习(三)多线程开发带来的问题与解决方法
  3. Redis数据迁移的4种方法
  4. IDEA最新激活码2021(IDEA2020.3永久激活方法)
  5. Object对象你真理解了吗?
  6. HotSpot VM 中对象的内存分析
  7. 从对象生命周期的经验统计到垃圾回收算法
  8. 什么样的 Java 对象会被当垃圾回收?
  9. 模板方法模式在开源代码中应用

随机推荐

  1. 三分钟看完「分糖果」算法问题
  2. 五分钟小知识之什么是前缀表达式
  3. 盖尔-沙普利算法告诉你,你的对象在哪里?
  4. 浅谈什么是动态规划以及相关的「股票」算
  5. 这道算法题太太太太太简单啦
  6. 好吧,又是两分钟看完一道投机取巧的算法题
  7. 小知识:什么是「欧几里得算法」
  8. 浅谈什么是图拓扑排序
  9. 【三分钟】买卖股票的最佳时机 II 的另类
  10. 面试官,我会写二分查找法!对,没有 bug 的那