1.基于注解,首先我们是通过@EnableAspectJAutoProxy()这个注解开起AOP功能,这个注解会导入AspectJAutoProxyRegistrar组件从而将AnnotationAwareAspectJAutoProxyCreator注册到bean定义中。

2.如果容器有对应名字的bean定义,判断下是不是这个class,如果不是就改成AnnotationAwareAspectJAutoProxyCreator,如果没有就直接注册进去,注册bean定义名字叫org.springframework.aop.config.internalAutoProxyCreator。

3.AnnotationAwareAspectJAutoProxyCreator看来这个类是比较重要的了,我们看一下它的继承关系图,可以看到这个类扩展了那些接口,可以看到他是BeanPostProcessor的实现类

4.现在就直接来看之前在bean的实例化过程中第五点提到的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation这个方法中是寻找切面的过程。这个方法中其实就是去调用我们相应处理器的before和after方法

在applyBeanPostProcessorsBeforeInstantiation方法中我们看到其实会去调用InstantiationAwareBeanPostProcessor这个接口的postProcessBeforeInstantiation这个方法。从我们上面类图中可以看到。我们通过@EnableAspectJAutoProxy注解注册进去的AnnotationAwareAspectJAutoProxyCreator这个正是InstantiationAwareBeanPostProcessor这个的实现类,所以在这里必然会去调用AnnotationAwareAspectJAutoProxyCreator这个实现,但是这里使用了模板方法的设计模式,实际上的方法实现在其父类AbstractAutoProxyCreator这个中的方法。

5.在AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法中会去判断当前创建的类是否是基础类,是否跳过设置,正是shouldSkip这个方法将切面找出来。

6.shouldSkip中会先调用父类的findCandidateAdvisors找事务切面,再调用自己的builder找其他的切面。

7.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans中会获取到所的bean,循环判断是否是切面类,也就是是否标注了@Aspect注解的,再获取切面类中的增强器,也就是@After,@Before,@AfterReturning,@AfterThrowing,@Around这几个。找到了之后再加入到缓存中。

8.后面的类再进来就直接缓存里面拿出来就行了,不需要再去寻找切面了

9.接下来就是在在bean创建好之后会通过bean的后置处理器创建代理对象返回,并且在代理对象中织入我们的增强器。

10.现在来看AbstractAutoProxyCreator#postProcessAfterInitialization这个方法中的一些逻辑,从缓存中拿到我们之前的找到的增强器信息,并且找到匹配当前类的增强器。

11.找到之后又有一步排序的操作,这个就决定了我们增强器的执行顺序。找到了增强器说明需要生成代理,没有增强器就不需要代理。

12.如果需要创代理对象,则判断我们代理分方式@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true),第一个参数是是否暴露我们代理对象,如果暴露了可以当前原型类中通过AopContext.currentProxy(),获取到代理对象。如下图两种调用方式:一种会被切,一种不会

第二个参数是是否强制只用cglib代理。

判断是何种代理

13.可以看到返回的代理对象里面是有我们的增强器信息的。

至此切面寻找,代理对象创建,增强器织入都完成了,接下来就是我们执行目标方法的时候,这些增强器是如何执行的。

14.代理对象调用方法的时候会将增强器转换成拦截器链,就是根据上说到的排序顺序。

如下图:

15.然后创建一个反射方法的执行器执行proceed()方法 进行一个递归的调用,这里的调用有点绕,初始下标-1,然后通过前++的方式从拦截器链中获取出来执行,当最后都取完了的时候才执行目标方法,通过断点调试会发现调用顺序如下图:

因为是递归的调用所以最先执行结束却是54321的顺序,这就是为什么@Before是在方法执行之前执行,可以看到@AfterThrowing是在try-catch中执行的增强器方法。@After是在一个try-finally中执行的,所以这个始终会被执行。

这就是整个Spirng整个AOP的流程。

Spring aop(1)--- 寻找切面和代理对象执行流程源码分析的更多相关文章

  1. Spring Boot的自动配置原理及启动流程源码分析

    概述 Spring Boot 应用目前应该是 Java 中用得最多的框架了吧.其中 Spring Boot 最具特点之一就是自动配置,基于Spring Boot 的自动配置,我们可以很快集成某个模块, ...

  2. Spring Cloud学习 之 Spring Cloud Ribbon(执行流程源码分析)

    Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 文章目录 分析: 总结: 分析: ​ 在上篇文章中,我们着重分析了RestTempla ...

  3. Spring -- aop(面向切面编程),前置&后置&环绕&抛异常通知,引入通知,自动代理

    1.概要 aop:面向方面编程.不改变源代码,还为类增加新的功能.(代理) 切面:实现的交叉功能. 通知:切面的实际实现(通知要做什么,怎么做). 连接点:应用程序执行过程期间,可以插入切面的地点. ...

  4. spring AOP AspectJ 定义切面实现拦截

    总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1.  讲AOP之前,先来总结web项目的几种拦截方式    A:  过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...

  5. Spring AOP系列(一)— 代理模式

    Spring AOP系列(一)- 代理模式 AOP(Aspect Oriented Programming)并没有创造或使用新的技术,其底层就是基于代理模式实现.因此我们先来学习一下代理模式. 基本概 ...

  6. Spring加载流程源码分析03【refresh】

      前面两篇文章分析了super(this)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码, Spring加载流程源码分析01[su ...

  7. 转:Spring与Mybatis整合的MapperScannerConfigurer处理过程源码分析

    原文地址:Spring与Mybatis整合的MapperScannerConfigurer处理过程源码分析 前言 本文将分析mybatis与spring整合的MapperScannerConfigur ...

  8. Java的三种代理模式&完整源码分析

    Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCache缓存的实现机制](https://www.c ...

  9. spring boot 加载web容器tomcat流程源码分析

    spring boot 加载web容器tomcat流程源码分析 我本地的springboot版本是2.5.1,后面的分析都是基于这个版本 <parent> <groupId>o ...

随机推荐

  1. doc文件转txt

    doc文件转txt # -*- coding:utf-8 -*- # 安装pywin32包 http://sourceforge.net/projects/pywin32/files/pywin32/ ...

  2. 关于tomcat启动错误:At least one JAR was scanned for TLDs yet contained no TLDs

    一.问题原因: 1.出现这个问题的原因就是Tomcat启动时会扫描大量jar包,如果含有不符合TLD规范的就会出现这个问题 2.以后基本上不会使用JSP作为视图层,所以我们可能根本不需要TLD这个东西 ...

  3. 发布订阅--DBMS "无法作为数据库主体执行,因为主体“dbo”不存在、无法模拟这种..........”

    解决方案: 新附加的数据库需要设置所有者才能建立数据库关系图.供参考的操作步骤如下: 选择“AdventureWorks2012LT”,右键,选择“属性”,选择“文件”页,点击“所有者”右侧按钮,点击 ...

  4. D. Coloring Edges

    You are given a directed graph with 

  5. py学习笔记1.13、1.14

    1.name.title() 首字母大写 name.upper() 全部大写 name.lower() 全部小写 2.+ 合并字符串 3.单引号.双引号都可以表示字符串 4.# 注释 5.索引制定为- ...

  6. AOP实现防止接口重复提交

    项目中对于状态变更接口存在重复提交的问题. package com.yxx.survey.foundation.aop; import com.alibaba.fastjson.JSON; impor ...

  7. day20-双下new方法,单例模式

    # 1. __new__:构造方法,它创造对象,程序员口头语:new一个对象.先执行__new__方法再执行___init__方法. class Goods: def __init__(self):# ...

  8. mean|mode|median|sample的表达方式

    Measures of Center measures of central tendency:the center or most typical value:average Mean:its ar ...

  9. AI动作捕捉技术,会让制造业大幅度降低成本吗?

    现代动作捕捉系统应该是起源于100多年前的动画工业,通过一种叫做"动态遮罩或影像描摹"的技术,动画师们可以获得流畅的.栩栩如生的动作:后来到了20世纪80年代,动画师们设计出带有活 ...

  10. vs2015的密钥

    最近一直提示VS要登陆,登陆完就说评估期已到,搞得很烦. VS2015 enterprise版本得密钥:  HM6NR-QXX7C-DFW2Y-8B82K-WTYJV    亲测有效!!! 专业版本的 ...