什么是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. Python小游戏 -- 猜单词

    Python初学者小游戏:猜单词 游戏逻辑:就像我们曾经英语学习机上的小游戏一样,电脑会从事先预置的词库中抽取单词,然后给出单词的字母数量,给定猜解次数,然后让玩家进行猜测,并给出每次猜测的正确字母与 ...

  2. UVA10020(最小区间覆盖)

    题意:       给你一个区间[0,m]和一些小的区间[l,r]让你选择最少的小区间个数去把整个区间覆盖起来. 思路:       算是比较经典的贪心题目吧(经典于难度没什么对应关系),大体思路可以 ...

  3. POJ2349二分+并查集,类似最小树的贪心

    题意:       给你n个点,你的任务是构建一颗通讯树,然后给你一个s表示可以选出来s个点两两通讯不花钱,就是费用是0,其他的费用就是两点的距离,有个要求就是其他的费用中最大的那个最小. 思路:   ...

  4. Wampserver-删除虚拟主机

    对hosts操作 到目录C:\Windows\System32\drivers\etc中修改hosts 比如你想删除iwh2.com 选中这2行进行删除,保存退出 对httpd-vhosts操作 到目 ...

  5. PHP中文转拼音扩展

    Pinyin 基于 CC-CEDICT 词典的中文转拼音工具,更准确的支持多音字的汉字转拼音解决方案. 安装 使用 Composer 安装: $ composer require "over ...

  6. Redis数据结构—跳跃表

    目录 Redis数据结构-跳跃表 跳跃表产生的背景 跳跃表的结构 利用跳跃表查询有序链表 Redis跳跃表图示 Redis跳跃表数据结构 小结 Redis数据结构-跳跃表 大家好,我是白泽,最近学校有 ...

  7. Consul 服务的注册和发现

    Consul 是Hashicorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.Consul是分布式的,高可用的,可横向扩展的. Consul 的主要特点有:    Service Disc ...

  8. x265 code tracing

    方瑞东的博客专栏 http://blog.csdn.net/frd2009041510/article/details/51182920 cabbage2008的专栏 http://blog.csdn ...

  9. Java并发-显式锁篇【可重入锁+读写锁】

    作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized: 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock.读写 ...

  10. 虚拟机快速下载安装配置aarch64-linux-gnu-gcc工具链

    方式一:软件仓库安装 此方法不用自己去配置交叉编译工具链 1.查看本地仓库有支持哪些版本哪些 输入命令: apt-cache search aarch64 2.下载安装 gcc-8-aarch64-l ...