Spring系列——AOP(概念+常用的三种AOP实现方式+日志打印Demo)

本文深入探讨了Spring AOP,包括基本概念如连接点、切点、增强、代理和切面,以及适用场景。详细介绍了AOP的三种实现方式:JDK动态代理、CGLib动态代理及其优缺点。此外,还通过实例展示了如何通过实现接口、@AspectJ注解和XML配置实现AOP,最后讨论了日志打印的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概念

1.1 基本概念

AOP是Aspect Oriented Programing缩写,即面向切面编程。

AOP通过横向抽取机制为无法通过纵向继承体系进行抽象的重复性代码提供了解决方案。AOP希望将分散在各个业务逻辑代码中的相同代码通过横向切割的方式抽取到一个独立的模块中。

连接点Joinpoint

程序执行的某个特定位置,比如类初始化前、类初始化后、类的某个方法调用前、后、方法抛出异常后。

Spring仅支持方法的连接点,即仅能在方法调用前、后方法抛出异常时及方法调用前后这些执行点织入增强。

切点Pointcut

AOP通过切点定位特定的连接点(类比通过切点筛选符合条件的连接点)
Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。确切讲为执行点,因为切点仅定位到某个方法上,而连接点包括方位信息,比如执行前/后。

增强Advice

增强是织入目标类连接点上的一段程序代码。
Spring提供的增强接口都是带方位名的,比如BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。只有结合切点和增强才能确定特定的连接点并实施增强逻辑。

目标对象Target

增强逻辑的织入目标类
目标类只实现非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。

引介Introduction

引介是一种特殊的增强,它为类添加一些属性和方法。即使一个业务类原本没有实现某个接口,通过AOP的引介功能,也能动态地为业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

织入Weaving

织入是将增强添加到目标类的具体连接点上的过程。

AOP的3种织入方式:

  • 编译器织入,这要求使用特殊的Java编译器。
  • 类装载期织入,这要求使用特殊的类加载器。
  • 动态代理织入,在运行期为目标类添加增强生成子类的方式。

代理Proxy

一个类被AOP织入增强后,就产生一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以可以采用与调用原类相同的方式调用代理类。

切面Aspect

切面由切点和增强(引介)组成,它既包括横切逻辑的定义,也包括连接点的定义。Spring AOP就是负责实施切面的框架,它将所定义的横切逻辑织入切面所指定的连接点中。

AOP实现关键点

AOP的工作重点在于如何将增强应用在目标对象的连接点上。包括两项工作:第一,如何通过切点和增强定位到连接点;第二点,如何在增强中编写切面代码。

1.2 适用场景

AOP是有特定的应用场合的,只适合那些具有横切逻辑的应用场合,如性能检测、访问控制、事务管理以及日志记录。

1.3 AOP代理机制

Spring AOP 在运行期通过代理方式向目标类织入增强代码,在Spring中可以无缝地将Spring AOP IOC 和AspectJ整合在一起。

Spring AOP 使用了两种代理机制,一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。使用两种代理机制的原因是JDK本身只提供接口的代理,而不支持类的代理。

JDK动态代理

JAVA提供了动态代理技术,允许开发者在运行期创建接口的代理实例。

JDK动态代理主要涉及java.lang.reflect包中的两个类:Proxy和Invocation。

  • Invocation是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态地将横切逻辑和业务逻辑编制在一起。
  • Proxy利用Invocation动态创建一个符合某一接口的实例,生成目标类的代理对象。

CGLib动态代理

CGLib动态代理采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截技术拦截所有父类方法的调用并顺势织入横切逻辑。

由于CGLib使用动态创建子类的方式生成代理对象,所以不能对目标类中final或private方法进行代理。

JDK VS CGLib

CGLib所创建的动态代理对象的性能比JDK所创建的动态代理对象的性能高很多(约10倍),但CGLib在创建代理对象时花费的时间却比JDK代理多(约8倍)。
因此对于singleton的代理对象或者具有实例池的代理,无需频繁的创建代理对象,适合采用CGLib动态代理技术;反之适合采用JDK代理技术。

1.4 增强类

Spring 使用增强类定义横切逻辑,同时增强还包括在方法的哪一点加入横切代码的方位信息,所以增强即包括横切逻辑,又包含部分连接点的信息。

按照增强在目标类方法中的连接点位置,可以分为以下5类:

  • 前置增强:org.springframework
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值