AOP:Aspect Oriented Programming的缩写,面向切面编程,它的思想是将与业务逻辑无关的功能抽象出来,然后通过配置指定哪些功能怎样应用到业务逻辑方法中。如常用的日志记录、安全控制、事务处理,它们都是一些通用的与业务逻辑无关的功能,可以将其抽象出来,不必要在所有的方法代码中都重复调用一次(如果后期发现接口、逻辑有修改,是不是所有的调用代码都要调整?)。我们可以通过一定的配置指定哪些方法需要记录日志,哪些需要安全控制,哪些需要配置事务;可以指定在方法执行前、后或异常抛出时进行调用;总之,可以很灵活的进行全局配置,达到将独立功能嵌入到现有逻辑中。
AOP是一种思想,每个人都可以实现它,只要最终能满足自己要求,可以降低程序的耦合、提高可重用性。但是,这样有一个问题,如果哪天发现别人的实现比自己的实现更好,比如性能更快、更简洁、更容易扩展,就想直接切换过去,可在切换的时候才发现根本不能简单透明(不修改项目现有代码或很少修改)的调整。因为,虽然功能一样,但是接口、配置都不一致。因此,为了更好的促进AOP的发展,统一规范,出现了一个叫AOP联盟的组织,负责制定AOP相关接口规范,对AOP编程思想进行了高度抽象,提出通知、连接点、拦截器等概念,整个接口API很简洁,如图所示:
现在AOP的实现很多,有Spring AOP、AspectJ、AspectWerkz等,下面主要分析Spring AOP的实现。
要将抽象的与业务逻辑无关的功能(如上所说的日志记录)动态的应用到业务逻辑代码中,常用的技术就是代理。Spring AOP实现也是采用代理方式,代理目标对象,根据配置将添加的功能通过代理调用。AOP代理就是一个代理,只是基于AOP思想生成而已。
首先,介绍几个AOP术语:
1、Advice(通知),定义具体要做什么,如上面所说的日志记录、安全控制。有时也称为“增强”,对目标方法进行功能增强。
2、Joinpoint(连接点),定义通知执行的代码位置,如在哪个方法执行。
3、Pointcut(切点),定义通知在哪些连接点上执行,即定义连接点的一个集合,通常配置一个正则表达式匹配一系列方法集合。
4、Advisor(通知器),将通知和切点关联起来,定义了哪个通知用于哪个切点。
接着,看看AOP代理是如何生成的。
Spring提出了一个工厂bean(FactoryBean)的概念,既是一个创建bean的工厂,又是BeanFactory的一个bean。通过它可以完全自定义需要的任何bean,不再受bean标签指定的特定class束缚,因为在获取工厂bean的时候实际上返回的是getObject()返回的对象,而不是工厂bean本身。因此,创建bean代理也可以通过类似的方式实现,在getObject()中对目标bean进行代理,将要增加的功能添加到代理对象。ProxyFactoryBean就是创建AOP代理具体实现,比如常见的属性targetName(代理目标)、interceptorNames(通知器/通知名称),创建过程为:
1、根据配置的通知器(interceptorNames值)构造一个拦截器(通知器)链,实际调用的时候会依次执行。其实就是根据配置的通知器名称找到对应的bean,并添加到List集合。
2、创建代理对象,并在调用时候加入拦截器的调用。
如果是接口,就直接采用JDK动态代理;否则就采用CGLIB生成代理。代理创建好了,对拦截器链的调用才是核心,这里以JDK代理为例分析拦截器链是怎么调用的。在ReflectiveMethodInvocation的proceed方法中,会逐个执行拦截器的拦截方法,但是在执行拦截方法之前,会对代理方法进行匹配校验,满足的才进行拦截。整个递归迭代原理是在MethodInvocation(看具体实现ReflectiveMethodInvocation)的proceed方法中,调用MethodInterceptor的invoke方法,在invoke方法中,返回MethodInvocation的proceed结果,而在proceed的处理中,又会进行下一个MethodInterceptor调用。通过代码更容易理解,如下:
ReflectiveMethodInvocation的proceed方法(部分逻辑): public Object proceed() throws Throwable { //从拦截器链中依次取出拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //调用拦截器的拦截方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } } MethodBeforeAdviceInterceptor的invoke方法: public Object invoke(MethodInvocation mi) throws Throwable { //该拦截器的通知具体调用地方,比如此处为方法调用前置通知,那么增强的功能就在方法执行前调用 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); }
简单的讲,AOP代理就是添加了一个拦截器链调用,而Spring AOP拦截器其实就是Spring实现的Advice。下面展示Spring Advice实现类层次关系图:
上图左边是AOP规范接口,右边是Spring AOP实现。Spring将通知(功能增强)和拦截器分开实现,然后采用拦截器包装通知的方式,又抽象了一层功能,降低了代码耦合,增加了使用的灵活性。最后,为了使用拦截器链的方便,为每个通知配置了一个适配器,并将适配器注册到全局注册表DefaultAdvisorAdapterRegistry中,而AOP代理在根据配置的通知器(Advisor)获取匹配的通知(Advice)时会通过MethodInterceptor[] getInterceptors(Advisor advisor)方法转换为标准MethodInterceptor,这就取得了拦截器链。
相关推荐
spring-aop 源代码包spring-aop 源代码包spring-aop 源代码包spring-aop 源代码包spring-aop 源代码包spring-aop 源代码包spring-aop 源代码包
AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析...
一、适合人群 1、具备一定Java编程基础,初级开发者 ...(需要知道原理的请看spring aop源码,此处不做赘述) 3、可在现有源码上快速进行功能扩展 4、spring boot,mybatis,druid,spring aop的使用
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象...
Java spring AOP源码
Spring AOP(面向切面编程)作为Spring框架的一个重要部分,为Java开发者提供了一个...通过对Spring AOP源码的深入分析,我们可以更好地理解其内部工作原理,从而在实际开发中更加灵活和高效地使用这一强大的编程范式。
1.Spring入门和IOC介绍 2.对象依赖 3.AOP入门 4.JDBCTemplate和Spring事务 5.Spring事务原理 6.Spring事务的一个线程安全问题 7.IOC再回顾和面试题 8.AOP再回顾
Spring源码最难问题:当Spring AOP遇上循环依赖.docx
基于spring4实现的AOP源代码。此源代码解压即用。
Spring-Aop源码实现
Spring Aop 引用 源码
spring aop 源码解析
spring-aop-4.2.4.RELEASE-sources.jar;spring框架源码
Spring AOP源码笔记
spring-aop 源码电子书,本人根据spring-aop的源码整理生成的pdf ,方便在kindle上阅读
Spring Aop 源码流程.doc
有关于Spring,我们最常用的两个功能就是IOC和AOP,前几篇文章从源码级别介绍了Spring容器如何为我们生成bean及bean之间的依赖关系 下面我们接着来看AOP的源码实现。 有关于AOP,我们在面试中也被无数次问到...
NULL 博文链接:https://306963591.iteye.com/blog/1129837
Java流行框架源码分析:Spring源码、SpringBoot源码、SpringAOP源码、SpringSecurity源码、SpringSecurity OAuth2源码、JDK源码、Netty源码
NULL 博文链接:https://zhang-yingjie-qq-com.iteye.com/blog/319927