
文章图片

文章图片

文章图片
话不多说 , 发车!
说下 AOPAOP , Aspect Oriented Programming , 面向切面编程 。
将一些通用的逻辑集中实现 , 然后通过 AOP 进行逻辑的切入 , 减少了零散的碎片化代码 , 提高了系统的可维护性 。
具体是含义可以理解为:通过代理的方式 , 在调用想要的对象方法时候 , 进行拦截处理 , 执行切入的逻辑 , 然后再调用真正的方法实现 。
例如 , 你实现了一个 A 对象 , 里面有 addUser 方法 , 此时你需要记录该方法的调用次数 。
那么你就可以搞个代理对象 , 这个代理对象也提供了 addUser 方法 , 最终你调用的是代理对象的 addUser, 在这个代理对象内部填充记录调用次数的逻辑 , 最终的效果就类似下面代码:
Enhancer en = new Enhancer();
//2.设置父类 , 也就是代理目标类 , 上面提到了它是通过生成子类的方式
en.setSuperclass(target.getClass());
//3.设置回调函数 , 这个this其实就是代理逻辑实现类 , 也就是切面 , 可以理解为JDK 动态代理的handler
en.setCallback(this);
//4.创建代理对象 , 也就是目标类的子类了 。
return en.create();
JDK 动态代理和 CGLIB 两者经常还可能被面试官问性能对比 , 所以咱们也列一下(以下内容取自:haiq的博客):
- jdk6 下 , 在运行次数较少的情况下 , jdk动态代理与 cglib 差距不明显 , 甚至更快一些;而当调用次数增加之后 ,cglib 表现稍微更快一些
- jdk7 下 , 情况发生了逆转!在运行次数较少(1000000)的情况下 , jdk动态代理比 cglib 快了差不多30%;而当调用次数增加之后(50000000) ,动态代理比 cglib 快了接近1倍
- jdk8 表现和 jdk7 基本一致
能说说拦截链的实现吗?我们都知道 Spring AOP 提供了多种拦截点 , 便捷我们对 AOP 的使用 , 比如 @Before、@After、@AfterReturning、@AfterThrowing 等等 。
方便我们在目标方法执行前、后、抛错等地方进行一些逻辑的切入 。
那 Spring 具体是如何链起这些调用顺序的呢?
这就是拦截链干的事 , 实际上这些注解都对应着不同的 interceptor 实现 。
然后 Spring 会利用一个集合把所有类型的 interceptor 组合起来 , 我在代码里用了 @Before、@After、@AfterReturning、@AfterThrowing这几个注解 。
于是集合里就有了这些 interceptor(多了一个 expose...等下解释) , 这是由 Spring 扫描到注解自动加进来的:
然后通过一个对象 CglibMethodInvocation 将这个集合封装起来 , 紧接着调用这个对象的 proceed 方法 , 可看到这个集合 chain 被传入了 。
我们来看下 CglibMethodInvocation#proceed 方法逻辑 。
要注意 , 这里就开始 递归套娃 了 , 核心调用逻辑就在这里:
可以看到有个 currentInterceptorIndex 变量 , 通过递归 , 每次新增这索引值 , 来逐得到下一个 interceptor。
并且每次都传入当前对象并调用 interceptor#invoke, 这样就实现了拦截链的调用 , 所以这是个递归 。
我们拿集合里面的 MethodBeforeAdviceInterceptor 来举例看下 , 这个是目标方法执行的前置拦截 , 我们看下它的 invoke 实现 , 有更直观的认识:
invoke 的实现是先执行切入的前置逻辑 , 然后再继续调用 CglibMethodInvocation#proceed(也就是mi.proceed) , 进行下一个 interceptor 的调用 。
总结下 :
Spring 根据 @Before、@After、@AfterReturning、@AfterThrowing 这些注解 。
往集合里面加入对应的 Spring 提供的 MethodInterceptor 实现 。
比如上面的 MethodBeforeAdviceInterceptor, 如果你没用 @Before , 集合里就没有 MethodBeforeAdviceInterceptor。
然后通过一个对象 CglibMethodInvocation 将这个集合封装起来 , 紧接着调用这个对象的 proceed 方法 。
具体是利用 currentInterceptorIndex 下标 , 利用递归顺序地执行集合里面的 MethodInterceptor, 这样就完成了拦截链的调用 。
- iPhone|挑手机别只看iPhone,值得入手的国产5G旗舰推荐,看看哪款你在用
- 裁员|阿里腾讯被爆裁员20%最直接反映了实体经济与互联网产业的区别!
- iPhone|2022换手机千万别抠搜,这4款手机最值得入手,用个三五年没问题
- 裁员|互联网大厂大规模裁员,别抱怨,毕业式裁员是给打工人最后的体面
- 网购|实体店家电有保障,业内人士道出实情:别再傻乎乎“网购”了
- 华为|裁员即毕业!京东多条业务线裁员,员工:压力特别大,要崩溃
- 华硕|华硕无双值得买吗?别犹豫了,首销日它已经登上京东热卖榜
- 对开门冰箱|三开门的冰箱和对开门的冰箱,究竟哪个更值得投入?来谈谈区别
- iPhone|苹果13pro和苹果13pormax的区别在哪里?
- iPhone|iPhone面临淘汰的3个信号:别纠结,一旦发现就该换手机了
