Spring--AOP的见解
AOP是指面向切面编程,与JAVA中的动态代理有很深的渊源。
在使用Spring框架时,AOP编程能简化很多繁杂的步骤,精简代码。
切面:横切关注点(跨越程序中多个模块的功能),被模块化的特殊对象,也可以认为是抽取了一些通用的东西当成一个“面”;
通知:切面必须要完成的工作(切面中的每一个方法被称之为通知),可以认为抽取出来的切面(类)中的方法都是一个通知;
目标:被通知的对象(业务逻辑),也就是被包裹的方法。或者说要实现的目标方法;
代理:向目标对象应用通知之后创建的对象;
连接点:程序执行的某个特定位置(比如调用某一方法之前,调用某一方法之后);
由以下两个基本信息来决定:
- 方法:这个方法就是表示程序的执行点(程序执行到了此处);
- 相对点:相对点执行的方位(即当前执行方法之前?之后?异常时?)
切点:每个类都会有很多个连接点(因为一个类可以有多个方法,所以会存在很多个切入点);
AOP通过切点定位到特定的连接点
连接点相当于数据库中的一条数据,是真实存在的。而切入点则是查询这个数据的方法。也就是说一个切点(条件)可以多个连接点(查到很多的记录)
AOP的原理(注解版):
- @EnableAspectJAutoProxy:开启AOP功能;
- @EnableAspectJAutoProxy:这个注解会给容器注册一个组件AnnotationAwareAspectJAutoProxyCreator;
- AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
- 容器创建流程:
- registerBeanPostProcessors()注册后置处理器创建对象AnnotationAwareAspectJAutoProxyCreator;
- finishBeanFactoryInitialization()初始化剩下的单实例Bean:
- 床架业务逻辑组件和切面组件;
- AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程;
- 组件创建完成之后判断组件是否需要被包装(增强);如果需要就将切面的通知方法包装成增强器(advisor);给业务逻辑组件创建一个代理对象;
- 目标方法执行:
- 代理对象执行目标方法;
- cglibAopProxy.intercept();
- 得到目标方法的拦截器(增强器包装成MethodInterceptor);
- 利用拦截器的链式机制,依次进入每个拦截器执行;
2. @EnableAspectJAutoProxy:这个注解会给容器注册一个组件AnnotationAwareAspectJAutoProxyCreator:
- 首先是由配置类创建IOC容器
- 注册配置类,调用refresh()刷新容器
- registerBeanPostProcessors(beanFactory);注册Bean的后置处理器(这个关系到AOP的后置拦截器,他专拦截Bean创建)来方便拦截Bean创建:
- 首先获取IOC容器一定定义好的需要创建对象的所有后置处理器;
- 给容器中加入别的Bean的后置处理器;
- 有限注册实现了PriorityOrdered接口的Bean的后置处理器,再来是实现了Ordered接口Bean的后置处理器;最后是注册那些没有实现(标注)优先级接口的Bean的后置处理器;
- 注册其实就是创建后置处理器并且保存在IOC容器中,因为这是在创建IOC容器;
- 创建Bean实例;
- populateBean:给Bean的各种属性赋值;
- initializeBean:初始化Bean的方法
- invokeAwareMethods():处理Aware接口的方法回调;
- applyBeanPostProcessorsBforeInitlization:前置方法调用;
- invokeinitMethids()初始化方法;
- 调用后置方法applyBeanPostProcessorsAfterInitlization;
- BeanPostProcessor创建成功,开始搞那些Bean实例化什么的常规操作;
3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器:他会试图拦截每一个Bean的创建,并且返回一个对象 || 容器创建流程
- 在每一个Bean创建之前都调用PostProcessBeforeInstantiation()方法;
- 判断当前Bean是否在adviseBeans中;
- 判断当前Bean是不是基础类型(Advice,Pointcut,Advisor,AopIntrastructureBean),或者是切面@Aspect;
- 判断是否需要跳过
- 判断候选增强器(就是指这个切面中的方法),每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor类型;
- 判断每一个增强器是否是AspectJPointcutAdvisor类型返回True;
- 其他的永远返回false;
- 创建好对象之后,后置方法postProcessAfterInitialization:return warpIfNecessary(bean,beanName,cachekey),在需要的时候包装(判断时候需要被切面环绕咯~)
- 获取所有的增强器(通知方法),封装未一个Object[ ]数组;
- 找到增强器(找到需要切入到当前程序运行时切入当前Bean的通知方法);
- 获取到当前Bean使用的增强器;
- 给增强器排个序;
- 保存Bean在adviseBean中;
- 如果当前Bean需要增强,创建Bean的代理对象
- 获取所有的增强器;
- 保存到proxyFactory中;
- 创建代理对象(这个有Spring来决定)
- JDK动态代理对象,JDKDynamicAopProxy(config);
- cglib动态代理对象,ObjenesisCglibAopProxy(config);
- 给容器中返回当前组件使用的cglib增强之后的代理对象;
- 之后在执行目标方法的时候,调用的就是这个已经被注入的代理对象;
- 获取所有的增强器(通知方法),封装未一个Object[ ]数组;
4.目标方法执行
- 容器中此时已经存在的是组件的cglib代理对象
- cglibAopProxy,interceot();拦截目标方法执行;
- 根据ProxyFactory对象获取拦截器链;
- list<Object> interceptorLIst保存所有的拦截器,这其中有一个ExposeInvocationInterceptor和其他的增强器;
- 遍历所有的增强器,将器转化为Intereceptor
- 将增强器转化成了list<MethodInterceptor>;转换完成之后返回一个MethodInterceptor数组;
- 如果没有拦截器链,也就是说他不被环绕,不被增强,那就直接执行目标方法;
- 如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链的信息都传入,创建一个cglibMethidInvocation对像,并调用record()方法;
- 执行拦截器链
5.拦截器的触发过程
- 如果没有拦截器、拦截器的索引或者拦截器数组大小未-1时、遍历拦截器的参数i增长到拦截器链长度时,会执行目标方法;
- 链式获取每一个拦截器,拦截器执行Invoke方法(这其实也在调用cglib的proceed()方法,让其继续获取下一个拦截器)
每一个拦截器都会在下一个拦截器调用完成后才执行。
applyBeanPostProcessorsBforeInitlization
Spring--AOP的见解的更多相关文章
- 什么是 Spring AOP 和代理
https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9403056301388627935% ...
- 求求你,下次面试别再问我什么是 Spring AOP 和代理了!
https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9403056301388627935% ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- spring aop
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将 ...
- spring aop注解方式与xml方式配置
注解方式 applicationContext.xml 加入下面配置 <!--Spring Aop 启用自动代理注解 --> <aop:aspectj-autoproxy proxy ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- Spring AOP详解
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- Spring AOP实例——异常处理和记录程序执行时间
实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
随机推荐
- python的各种包安装地址
http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy-stack 这个网页里有python的所有包,whl的后缀是python压缩包的意思.在windows ...
- 喵的Unity游戏开发之路 - 在球体上行走
很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本文不 ...
- 建设开发者生态:6项华为API管理原则落地
摘要: 为了向开发者提供良好.一致.稳定的华为API的体验,华为通过明确“API管理六项原则”,来支持开发者生态建设. 一个不开放的组织,会慢慢成为一潭僵水,一个封闭的系统,能量最终会耗尽,在产品开发 ...
- URL的字符编码
摘要: 在通过URL访问HTTP SERVER的时候,通常会产生trace callback的异常,返回505的错误," VERSION IS NOT SUPPORTED ?" , ...
- 详细了解JS Map,它和传统对象有什么区别?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://www.codeproject.com/Articles/5278387/Under ...
- Unity可视化数据:创建图表
本文由Aoi翻译,转载请注明出处.文章来自于catlikecoding,原文作者介绍了Unity制作图表.可视化数据的方法.更多的名词解释内容,请点击末尾的“原文链接”查看. 介绍 这个教程里,我 ...
- MySQL索引凭什么能让查询效率提高这么多?
点赞再看,养成习惯,微信搜一搜[三太子敖丙]关注这个喜欢写情怀的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系 ...
- ZT:15 个你非了解不可的 Linux 特殊字符
https://os.51cto.com/art/202003/611595.htm 不知道大家接触 Linux 系统有多久了,可曾了解过 Linux 中有哪些特殊的字符呢?其实啊,那些特殊字符都大有 ...
- 20190923-11Linux crond 系统定时任务 000 019
crond 服务管理 1.重新启动crond服务 [root@hadoop101 ~]# service crond restart centOS7是 systemctl restart crond ...
- Linux:网络基础配置
一.修改主机名 hostname 查看主机名 1.hostname zy 修改主机名为zy,临时生效,重新登录系统生效. 2.想要永久修改,,需修改配置文件: vi /etc/sysconf ...