Spring AOP原理

x33g5p2x  于2021-03-14 发布在 Spring  
字(3.0k)|赞(0)|评价(0)|浏览(350)

AOP的原理,也是非常简单的,即通过分离关注点让解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中就不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系则通过切面来封装、维护,这样原本分散在整个应用程序中的代码就可以很好的进行管理了。

实现原理

在编译期修改源代码、运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,这是AOP的具体实现方法,而他是由三个重要步骤来完成的,先是生成代理对象,然后是拦截器的作用,最后是编织的具体实现。AOP框架的丰富,其实很大程度上体现在这三个步骤上所具有的丰富技术选择,以及与IOC容器之间的无缝缝合。而如果以实现方法来分的话,则主要有两类:静态AOP(包括静态织入)和动态AOP(包含动态代理、动态字节码生成、自定义类加载器、字节码转换器)。

结构概述


AOP联盟定义的AOP体系结构把与AOP相关的概念大致分为由高到低、从使用到实现的三个层次。从上往下:

  1. 最高层是语言和开发环境,在这个环境中可以看到几个重要的概念:“基础”可以视为待增强对象或者说目标对象;“切面”通常包含对于基础的增强应用;“配置”可以看成是一种编织,通过在AOP体系中提供这个配置环境,可以把基础和切面结合起来,从而完成切面对目标对象的编织实现。
  2. AOP体系结构的第二层次为语言和开发环境提供支持的,在这个层次中可以看到AOP框架的高层实现,主要包括配置和编织实现两部分内容。例如配置逻辑和编织逻辑实现本身,以及对这些实现进行抽象的一些高层API封装。这些实现和API封装,为前面提到的语言和开发环境的实现提供了有力的支持。
  3. 最底层是编织的具体实现模块,各种技术都可以作为编织逻辑的具体实现方法,比如反射、程序预处理、拦截器框架、类装载器框架、元数据处理等等。

使用概况

AOP在 权限(Authentication)、缓存(Cache)、内容传递(Context passing)、错误处理(Error handling)、懒加载(Lazy loading)、调试(Debug)、日志(Log)、跟踪优化和校准(tracing、profiling and monitoring)、性能优化(Performance optimization)、持久化(Persistence)、资源池(Resource pooling)、同步(Synchronization)、事务(Transactions)等方面都有用处,可以说是可使用范围及广。下面我们就以一张思维导图来串联,以此来铺开与AOP相关的所有的知识点。


AOP通常包含以下相关术语:

  1. 目标对象(Target):包含连接点的对象。也被用来引用增强化或代理化对象。
  2. 代理(Proxy):AOP 框架创建的对象,包含增强。
  3. 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
  4. 切点(Pointcut):指定一个通知将被引发的一系列连接点。AOP 框架必须允许开发者指定切入点:例如,使用正则表达式。
  5. 增强(Advice):在特定的连接点AOP框架执行的动作。各种类型的增强包括“around”、“before”、“throws”增强等等。增强类型将在下面讨论。许多 AOP 框架都是以拦截器做增强模型,维护一个“围绕”连接点的拦截器链。
  6. 切面(Advisor):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事物管理是J2EE应用中横切关注点中一个很好的例子。切面一般是用 Advisor 或者 拦截器实现。
  7. 织入(Weaving):组装方面创建通知化对象。这可以在编译时完成(例如:使用AspectJ编译器),也可以在运行时完成。Spring 和其他一些纯 Java AOP 框架,使用运行时织入。
  8. 引入(Introduction):添加方法或字段到增强化类。
  9. 接口(IsModified):用于简化缓存。(这里作为补充)。

AOP增强类型(也叫 通知类型)包括:

  1. Before Advice(前置增强):在一个连接点之前执行的增强,但这个增强不能阻止流程继续执行到连接点(除非它抛出一个异常)。
  2. After Advice(后置增强,全称是 After returning advice 正常返回增强 ):在连接点正常完成后执行的增强,例如,如果一个正常返回,没有抛出异常。如果抛出异常则不会执行。
  3. Around Advice(环绕增强):包围一个连接点的增强,如方法调用,是最强大的增强。在方法调用前后完成自定义的行为。它们负责选择继续执行连接点或直接返回它们自己的返回值或抛出异常来执行。
  4. Throws Advice(抛出增强,全称是 After throwing advice 异常返回增强,也叫 Finally returning advice 最终返回增强):是最常用的增强类型。大部分是基于拦截器框架如Nanning或者JBoss4提供的Around增强。作用是,不管,是否正常执行,都会返回增强中的内容。
  5. Introduction Advice(引入增强):一种非常特殊的增强。它将新的成员变量、成员方法引入到目标类中。它仅能作用于类层次,而不是方法层次,所以他不能作用于任何切入点。

Spring AOP 实现原理

AOP模块是Spring的核心模块,尽管Spring中有自己的一套AOP实现,但在Java社区中是最完整AOP框架还是Aspectj,所以为了弥补自己的不足,也为了提供更加丰富的AOP解决方案,Spring对Aspectj做了集成。同时,再配合Spring的IOC容器,Spring推出了一个完善的AOP解决方法。

Spring AOP的核心技术是JDK的动态代理技术。Spring AOP是以动态代理技术为基础,设计出了一系列AOP的横切实现,比如:前置增强、返回增强、异常增强等等。同时,Spring AOP还提供了一系列的Pointcut来匹配切入点,可以使用现有的切入点来设计横切面,也可以扩展相关的Pointcut方法来切入需求。

在Spring AOP 中,我们一般是通过配置文件或者编程的方式来实现的。常见的配置方法有四种:1,配置 ProxyFactoryBean 显示设置 advisors、advice、target 等。2,配置 AutoProxyCreator 这种方式下,还是如以前一样定义 bean,但是从容器中获得的其实是代理对象。3,配置<aop:config>。4,配置 <aop:aspectj-autoproxy>,使用 AspectJ 的注解来表示之前以及切入点。而编程方式是直接通过 ProxyFactory 设置 target 对象,再通过 getProxy 方法来获取代理对象。

总的来说,在Spring AOP中,对于AOP的使用者来说,可能简单配置 Bean 即可,但仔细分析 Spring AOP 的内部设计就可以看到,为了让AOP起作用,需要参照前面的 AOP 实现原理来完成一系列过程,需要为目标对象建立代理对象,这个代理对象可以通过使用JDK的Proxy来完成,也可以通过第三方的类生成器CGLIB来完成。然后,还需要启动代理对象的拦截器来完成各种横切面的织入,这一系列的织入设计时通过一系列 Adapter 来实现的。通过一系列 Adapter 的设计,就可以把AOP的横切面设计和Proxy模式有机地结合起来,从而实现在 AOP 中定义各种织入方式(这里的源码部分可能不会涉及)。具体实现过程笔者会在后面的文章中详细阐述。

相关文章

微信公众号

最新文章

更多