Spring Aop 源码增强获取分享

 更新时间:2022年5月5日 13:05  点击:289 作者:​ 斜月   ​

1 前言

在前文中,已经讲述了 AOP 的后置处理器使用和方法,在本文中继续分享增强信息相关的源码,这里才是 AOP 的核心代码。

2 spring 增强器

之前已经讲述了 spring AbstractApplicationContext.refresh 方法,在以下方法中都会处理会处理 BeanPostProcessor 接口。

  • invokeBeanFactoryPostProcessors
  • registerBeanPostProcessors
  • finishBeanFactoryInitialization

增强器的获取,就是提取 @Aspect 注解标记的内容,这个操作一般是在后置处理器中进行处理,在 refresh 方法中调用 finishBeanFactoryInitialization 步骤中进行实现,最终可以追溯到 AbstractAutoProxyCreator.postProcessAfterInitialization。Spring 容器中注册的 AnnotationAwareAspectJAutoProxyCreator 父类就是 AbstractAutoProxyCreator ,继而调用 postProcessBeforeInstantiation 方法获取代理对象。

在实例化之后,初始化之后会调用 postProcessAfterInitialization 方法,

如下图所示:

如果有 @Aspect 注解的切面,则将通过 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 方法进行获取并放入缓存中。

这里的 findCandidateAdvisors 方法的解析和追踪,获取增强器需要追踪 AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors() 方法,其又调用了 BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 方法,主要的作用就是为了获取切面逻辑,即获取增强器。

在这里 this.advisorFactory.getAdvisors(factory) 是获取增强器的最终实现方法,在 ReflectiveAspectJAdvisorFactory 工程方法中,可以看到以下内容,这里采用的是委托模式:

以上是获取增强器的核心逻辑,对于如何解析切面逻辑的注解,则还需要从以下方法进行着手分析,主要就是 getPointcut 方法。

在该方法中,主要实现了以下功能:

  • 1 获取切点的信息,切点信息一般是指获取注解表达式的信息。
  • 2 根据切点信息生成增强实现,所有的实现类都由 InstantiationModelAwarePointcutAdvisorImpl 进行统一的封装。

这里的 instantiateAdvice 方法即是获取切面逻辑

invokeAdviceMethod 这个方法就是实际调用的方法。

findCandidateAdvisors 查找所有的增强器的解析,但是对于所有的增强器,不一定能适用于当前 Bean,还需要挑选适合的增强器,满足配置的通配符的增强器。这就用到了 findAdvisorsThatCanApply

BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 来获取所有的 Advisor。其核心逻辑如下图所示:

  • 1 获取所有的 beanName,这个 Spring 提供了 BeanFactoryUtils.beanNamesForTypeIncludingAncestors 方法来获取容器中所有的 beanName 信息。
  • 2 遍历所有的 beanName , 并找出声明有 AspectJ 注解的类。
  • 3 对标记为 AspectJ 注解的类进行增强器的提取。
  • 4 将提取增强的结果放入 advisorsCache 中。

以上便是获取增强器的全部过程,总结来说 wrapIfNecessary getAdvicesAndAdvisorsForBean buildAspectJAdvisors 都是核心的方法。

3 总结

本文讲了获取增强信息获取的源码,主要核心方法为wrapIfNecessarygetAdvicesAndAdvisorsForBean buildAspectJAdvisors,在后续文中将继续 AOP 代码的分享。

到此这篇关于Spring Aop 源码增强获取分享的文章就介绍到这了,更多相关Spring Aop内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://juejin.cn/post/7087465088617021448

[!--infotagslink--]

相关文章

  • PHP成员变量获取对比(类成员变量)

    下面本文章来给大家介绍在php中成员变量的一些对比了,文章举了四个例子在这例子中分别对不同成员变量进行测试与获取操作,下面一起来看看。 有如下4个代码示例,你认...2016-11-25
  • Spring AOP 对象内部方法间的嵌套调用方式

    这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • php 获取用户IP与IE信息程序

    php 获取用户IP与IE信息程序 function onlineip() { global $_SERVER; if(getenv('HTTP_CLIENT_IP')) { $onlineip = getenv('HTTP_CLIENT_IP');...2016-11-25
  • php获取一个文件夹的mtime的程序

    php获取一个文件夹的mtime的程序了,这个就是时间问题了,对于这个问题我们来看小编整理的几个例子,具体的操作例子如下所示。 php很容易获取到一个文件夹的mtime,可以...2016-11-25
  • Spring Cloud 中@FeignClient注解中的contextId属性详解

    这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25
  • 源码分析系列之json_encode()如何转化一个对象

    这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
  • Springboot如何实现Web系统License授权认证

    这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28
  • 如何获取网站icon有哪些可行的方法

    获取网站icon,常用最简单的方法就是通过website/favicon.ico来获取,不过由于很多网站都是在页面里面设置favicon,所以此方法很多情况都不可用。 更好的办法是通过google提供的服务来实现:http://www.google.com/s2/favi...2014-06-07
  • jquery如何获取元素的滚动条高度等实现代码

    主要功能:获取浏览器显示区域(可视区域)的高度 : $(window).height(); 获取浏览器显示区域(可视区域)的宽度 :$(window).width(); 获取页面的文档高度 $(document).height(); 获取页面的文档宽度 :$(document).width();...2015-10-21
  • jQuery 2.0.3 源码分析之core(一)整体架构

    拜读一个开源框架,最想学到的就是设计的思想和实现的技巧。废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过,不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery又给扫一遍我也不会照本宣科的翻译...2014-05-31
  • jquery获取div距离窗口和父级dv的距离示例

    jquery中jquery.offset().top / left用于获取div距离窗口的距离,jquery.position().top / left 用于获取距离父级div的距离(必须是绝对定位的div)。 (1)先介绍jquery.offset().top / left css: 复制代码 代码如下: *{ mar...2013-10-13
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • Jquery 获取指定标签的对象及属性的设置与移除

    1、先讲讲JQuery的概念,JQuery首先是由一个 America 的叫什么 John Resig的人创建的,后来又很多的JS高手也加入了这个团队。其实 JQuery是一个JavaScript的类库,这个类库集合了很多功能方法,利用类库你可以用简单的一些代...2014-05-31
  • 详解SpringCloudGateway内存泄漏问题

    这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
  • C#获取字符串后几位数的方法

    这篇文章主要介绍了C#获取字符串后几位数的方法,实例分析了C#操作字符串的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • jquery获取tagName再进行判断

    如果是为了取到tagName后再进行判断,那直接用下面的代码会更方便: $(element).is('input') 如果是要取到标签用作到别的地方,可以使用一下代码: $(element)[0].tagName 或: $(element).get(0).tagName...2014-05-31
  • Spring为什么不推荐使用@Autowired注解详析

    @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
  • DOM XPATH获取img src值的query

    复制代码 代码如下:$nodes = @$xpath->query("//*[@id='main_pr']/img/@src");$prurl = $nodes->item(0)->nodeValue;...2013-10-04
  • Springboot如何使用mybatis实现拦截SQL分页

    这篇文章主要介绍了Springboot使用mybatis实现拦截SQL分页,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-19
  • PHP 如何获取二维数组中某个key的集合

    本文为代码分享,也是在工作中看到一些“大牛”的代码,做做分享。 具体是这样的,如下一个二维数组,是从库中读取出来的。 代码清单: 复制代码 代码如下: $user = array( 0 => array( 'id' => 1, 'name' => '张三', 'ema...2014-06-07