什么是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. hdu4888 最大流(构造矩阵)

    题意:       让你构造一个矩阵,满足每一行的和,和每一列的和都等于他给的,还要判断答案是否唯一,还有一点就是矩阵内所有的数字都是[0,k]范围的. 思路:       这个题目看完就让我想起了h ...

  2. 逆向与分析-WebBrowserPassView消息分析

    逆向与分析-WebBrowserPassView消息分析 这个的源头是之前我写的一个博客: http://blog.csdn.net/u013761036/article/details/730427 ...

  3. ExtJS4中Ext.onReady、Ext.define、Ext.create

    1.Ext.onReady 说明:onReady内的语句块会在页面上下文加载后再执行. 2.Ext.define 说明:创建类,可以继承其他类,也可以被继承. 例子1: 1 <script ty ...

  4. JVM默认内存大小

    堆(Heap)和非堆(Non-heap)内存 按照官方的说法:"Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在Java虚拟机启动时创建的." ...

  5. layui select 动态赋值

    出现问题 赋值完成后页面不显示,没有效果 发现问题 赋值完成后需要重新渲染select 解决问题 form.render('select');

  6. 三、jmeter常用的元件及组件

    一.HTTP cookie Manager 用来储浏览器产生的用户信息,Stepping Thread Group 可用于模拟阶梯加压! 二.HTTP Cache Manager 缓存管理器(模拟浏览 ...

  7. 二、postman断言及正则表达式取值

    postman老式断言与新式断言总结:本文以微信开发者文档为例 断言处如图所示 一.老式断言 老式断言总结:var variables相当于代码中定义的变量,test['']=true;相当于pyth ...

  8. 将项目连接到远程仓库git

    方式一: git clone "git中的项目地址",此时会生成一个新的项目2.该步骤用于生成一个本地仓库 将需要提交的所有文件除了node_module.git以及输出文件dis ...

  9. 类的两个装饰器classmethod、staticethod和内置魔术方法

    一.两个装饰器@classmethod.@staticmethod @classmethod:把类中的绑定方法变成一个类方法,cls 就等于类名 有什么用? 1.在方法中任然可以引用类中的静态变量 2 ...

  10. C++虚函数 - 静态函数能否为虚函数 .

    1.virtual与静态函数 C++中,静态成员函数不能被声明为virtual函数. 例如,下面的程序会编译失败. #include<iostream> class Test { publ ...