什么是AOP?

1: 传统的OOP编程他的代码逻辑是一种自上向下, 而在这些自上而下的过程中会产生一些横切性的问题,比如说:日志信息,权限校验认证,事务等,

2: 这些横切性问题,往往与我们的主业务逻辑关系不大,并且散落在代码的各个地方,维护麻烦, AOP就是解决这个问题的,将主业务逻辑和这些横切性问题分离,达到解耦

如图所示:

SpringAop底层原理: 1:JDK代理, 2: cglib动态代理

对目标对象的方法进行前置处理,后置处理,这些处理的代码加到目标代码前后的过程叫: 织入, 那么 JDK代理和 cglib代理分别是什么时候织入呢? 编译期还是运行期? 如果是运行期,那么是在运行期spring容器初始化的时候织入?还是我们拿到这个目标对象的时候织入的(织入后将对象放入容器中)?

让我们一点一点深入了解

先说答案: 织入,实在运行期Spring容器初始化的时候织入的.它也属于Bean的生命周期一部分, 将生成的代理对象放入单例池中, spring容器初始化的时候, 会扫描xml,或者有@Component注解的类,根据这些类和他的注解(比如scope,islaze...)生成BeanDefinition,全部扫描完成的时候,BeanFactory就组建完成了,然后BeanFactoryPostProcessor,后置处理,在这个处理过程中,bean的属性注入,同时aop也生成了代理对象(放置了拦截器调用链),

使用AspectJ,步骤:

1: 添加依赖(aspectjweaver)

2: 配置类上添加注解:@EnableAspectJAutoProxy

3: 定义一个切面类(类上如果有这个注解@Aspect ,那么他就是一个切面类),并交给spring容器管理,@Component

4: 声明一个切点, 切面类中的某个方法上如果有这个注解(@PointCut("excution(* com.boo.service..(..))")), 关于切点表达式可以自己看官方文档

5: 定义通知: 如果一个方法上有注解@AfterReturning("com.aop.config.UserAspectJ.pointCut()"), 说明这个是后置通知, 括号中是指向当前切面类的切点

6: 启动容器,测试

那么在spring源码中是如何实现AOP的? 几个关键的类

https://www.cnblogs.com/51life/p/9243021.html , 这里引用别人的笔记..感谢他

1: 查看源码中Bean初始化过程中,是如何解析xml 中的aop:aspectj-autoproxy/,

AbstractApplicationContext类: 的refresh()方法中的obtainFreshBeanFactory(); 作用:初始化容器, 解析xml中的标签(包括 pointCut标签,ADVISOR标签,ASPECT标签...)将Bean转换为BeanDefiniton

2: refresh()方法中的registerBeanPostProcessors(beanFactory); 作用: 注册各种各样的Bean后置处理器,这里就包括了AspectJAwareAdvisorAutoProxyCreator(这个是aop后置处理器)

3: AbstractAutowireCapableBeanFactory类的initializeBean()方法: 作用是实例化Bean,并给Bean注入属性(这个方法中可以看到 各种 ...Aware...类的回调自身赋值属性 ), 这里就包括了目标对象的实例化和注入属性,目标对象生成之后,最后一步是AspectJAwareAdvisorAutoProxyCreator(这个是aop后置处理器)开始处理目标对象,AbstractAutoProxyCreator类中的 createProxy()方法,进而生成代理对象, 这里会看到有二种代理方式: JDK代理 cglib代理, 将生成的代理对象放入单例池

4: 代理对象生成之后,那么"织入"这个是如何实现呢? 拦截器实现. AbstractAutoProxyCreator类中的 createProxy()方法中不仅仅生成了代理对象, 生成代理对象的时候同时也将 拦截器调用链放置到代理对象中了, Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 这个this,就是调用自身的invoke()方法, 这个方法中可以看到 retVal = invocation.proceed();这个是AOP的核心,如何对目标进行增强的

1: AbstractApplicationContext类: 的refresh()----obtainFreshBeanFactory();---loadBeanDefinitions(beanFactory);---XmlWebApplicationCotnext类的loadBeanDefinitions()--loadBeanDefinitions(beanDefinitionReader);----reader.loadBeanDefinitions(configLocation);-----int count = loadBeanDefinitions(resources);----XmlBeanDefinitionReader类的loadBeanDefinitions----doLoadBeanDefinitions(inputSource, encodedResource.getResource());---documentReader.registerBeanDefinitions(doc, createReaderContext(resource));---parseBeanDefinitions(root, this.delegate);-----delegate.parseCustomElement(ele);(这个是解析其他的标签,而非默认的(beans,alias..))----handler.parse---ConfigBeanDefinitionParser类的parseAspect, 这里就可以看到解析POINTCUT 标签,ASPECT标签, 转换为BeanDefinition然后存入list中

2: refresh()----registerBeanPostProcessors(beanFactory); 这个方法的逻辑是,先获取所有的后置处理器,然后分类存储, 然后创建对应的处理器,这里就包括了AspectJAwareAdvisorAutoProxyCreator

3: AbstractAutowireCapableBeanFactory类的initializeBean()----applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);-----AbstractAutoProxyCreator类wrapIfNecessary(bean, beanName, cacheKey);---createProxy---proxyFactory.getProxy(getProxyClassLoader());----这里会看到二个实现类 CglibAopProxy JdkDynamicAopProxy

4: 织入的实现: AbstractAutoProxyCreator类中createProxy()----invoke()--List

SpringAOP 原理解析的更多相关文章

  1. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

  2. 【算法】(查找你附近的人) GeoHash核心原理解析及代码实现

    本文地址 原文地址 分享提纲: 0. 引子 1. 感性认识GeoHash 2. GeoHash算法的步骤 3. GeoHash Base32编码长度与精度 4. GeoHash算法 5. 使用注意点( ...

  3. Web APi之过滤器执行过程原理解析【二】(十一)

    前言 上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要.这一节我们简单将讲述在Action方法上.控制器上.全局上以及授 ...

  4. Web APi之过滤器创建过程原理解析【一】(十)

    前言 Web API的简单流程就是从请求到执行到Action并最终作出响应,但是在这个过程有一把[筛子],那就是过滤器Filter,在从请求到Action这整个流程中使用Filter来进行相应的处理从 ...

  5. GeoHash原理解析

    GeoHash 核心原理解析       引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段 ...

  6. alibaba-dexposed 原理解析

    alibaba-dexposed 原理解析 使用参考地址: http://blog.csdn.net/qxs965266509/article/details/49821413 原理参考地址: htt ...

  7. 支付宝Andfix 原理解析

    支付宝Andfix 原理解析 使用参考地址: http://blog.csdn.net/qxs965266509/article/details/49802429 原理参考地址: http://blo ...

  8. JavaScript 模板引擎实现原理解析

    1.入门实例 首先我们来看一个简单模板: <script type="template" id="template"> <h2> < ...

  9. Request 接收参数乱码原理解析三:实例分析

    通过前面两篇<Request 接收参数乱码原理解析一:服务器端解码原理>和<Request 接收参数乱码原理解析二:浏览器端编码原理>,了解了服务器和浏览器编码解码的原理,接下 ...

随机推荐

  1. POJ1789简单小生成树

    题意:       给你一些车牌号,然后另一两个车牌号之间的权值就是这两个字符串之间相同位置不同字母的个数,然后求最小生成树. 思路:       裸题,不解释了. #include<stdio ...

  2. 【python】Leetcode每日一题-旋转链表

    [python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...

  3. 批处理用WINRAR只压缩某类型的文件

    1:新建文件夹sql back 和 back,在sql back 文件夹内新建test1.dbb和test2.bak文件 2:新建批处理文件rar.bat,编辑文件: @echo off for %% ...

  4. ES6新增常用方法

    字符串新增方法 padStart.padEnd 如果原字符串不够指定长度,则会在左侧(右侧)填充字符串,用以补全 padStart( length: number, fillStr?: string ...

  5. SparkSQL电商用户画像(三)之环境准备

    五. 电商用户画像环境搭建 众所周知,Hive的执行任务是将hql语句转化为MapReduce来计算的,Hive的整体解决方案很不错,但是从查询提交到结果返回需要相当长的时间,查询耗时太长.这个主要原 ...

  6. 结对项目:求交点pro

    [2020 BUAA 软件工程]结对项目作业 项目 内容 课程:北航2020春软件工程 博客园班级博客 作业:阅读并撰写博客回答问题 结对项目作业 我在这个课程的目标是 积累两人结对编程过程中的经验 ...

  7. linux如何patch打补丁

    1. 创建2个文件 1.txt 和 2.txt 并在1.txt基础上修改成为2.txt book@100ask:~/patch$ ls 1.txt 2.txt book@100ask:~/patch$ ...

  8. 深入源码,深度解析Java 线程池的实现原理

    java 系统的运行归根到底是程序的运行,程序的运行归根到底是代码的执行,代码的执行归根到底是虚拟机的执行,虚拟机的执行其实就是操作系统的线程在执行,并且会占用一定的系统资源,如CPU.内存.磁盘.网 ...

  9. 对于uos目前只能安装商店的感慨,强制安装除外

    对于uos目前只能安装商店的感慨,强制安装除外 jie1018 / 2020-5-16 21:35 浏览: 702 / 回复: 26     个人觉得,在软件不足的情况下,更应该是系统支持,而不是让用 ...

  10. mysql基础之mysql主从架构半同步复制

    一.概念 1.异步复制(Asynchronous replication) MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样 ...