Spring AOP详解

一、配置方式

1.1、注解
@Aspect 声明该类为一个切面
@Pointcut 切入点
@Before 前置通知
@After 后置通知,方法执行完之后
@AfterReturning 返回通知,成功执行之后
@AfterThrowing 异常通知,抛出异常之后
@Around 环绕通知

1.2、XML

二、切入点表达式(Pointcut Expression)

|——>指示符(designator)
表达式(Expression)——> |——>通配符(wildcard)
|——>运算符(operator)

2.1、表达式符号

2.1.1、指示符
匹配方法:
execution()
匹配注解:
@target()、@args()、@within()、@annotation()
匹配包/类型:
within()
匹配对象:
this()、bean()、target()
匹配参数:
args()

2.1.2、通配符
*:匹配任意数量的字符
+:匹配指定的类及其子类
..:匹配任意数量的子包或参数

2.1.3、运算符
&&||!,匹配其他过滤条件,不多说,同Java

2.2、示例

2.2.1、匹配包/类型
//匹配UserService下所有的方法
@Pointcut("within(org.ljy.service.UserService)")
public void test(){...}

//匹配org.ljy包下的所有类的方法
@Pointcut("within(org.ljy.*)")
public void test(){...}

//匹配org.ljy包及其子包下的所有类的方法
@Pointcut("within(org.ljy..*)")
public void test(){...}

2.2.2、匹配对象
//匹配AOP对象的目标对象为指定类型,在此为DemoDao, this代表的是AOP代理对象
@Pointcut("this(org.ljy.DemoDao)")
public void test(){...}

//匹配实现了IDao接口的目标对象的方法, target为原始对象,即非AOP代理对象
@Pointcut("target(org.ljy.IDao)")
public void test(){...}
//匹配所有以Service结尾的bean里的方法, bean表示以bean的名字匹配
@Pointcut("bean(*Service)")
public void test(){...}

2.2.3、匹配参数
//匹配所有以find开头且只有一个参数类型为Long的方法
@Pointcut("execution(* *..find*(Long))")
public void test(){...}

//匹配所有只有一个参数且类型为Long的方法
@Pointcut("args(Long)")
public void test(){...}

//匹配所有以find开头且第一个参数类型为Long的方法
@Pointcut("execution(* *..find*(Long,..))")
public void test(){...}

//匹配所有第一个参数类型为Long的方法
@Pointcut("args(Long,..)")
public void test(){...}

2.2.4、匹配注解
//匹配方法上有MyAnno注解的方法
@Pointcut("@annotation(MyAnno)")
public void test(){...}

//匹配方法上有MyAnno注解的类里面的所有方法,要求MyAnno的RententionPolicy为CLASS级别
@Pointcut("@within(MyAnno)")
public void test(){...}

//匹配方法上有MyAnno注解的类里面的所有方法,要求MyAnno的RententionPolicy为RUNTIME级别
@Pointcut("@target(MyAnno)")
public void test(){...}

//匹配传入的参数的类上有MyAnno注解的方法
@Pointcut("@args(MyAnno)")
public void test(){...}

2.3、execution()表达式

2.3.1、格式
execution(modifer-pattern? returnType-pattern declaringType-pattern? name-pattern(param-pattern...) throws-pattern?)
翻译一下:
execution(修饰符? 返回类型 包名? 方法名(参数名...) 异常?)
【?表示可省略部分】
如:
//匹配修饰符为public,返回类型为User的org.ljy下以Service结尾的类下的所有方法
execution("public User org.ljy.*Service.*(..) ")

三、Spring AOP的实现原理

|——>代理模式
|——>设计模式——> |
| |——>责任链模式
实现原理——> |
| |——>JDK
|——>实现方式——> |
|——>cglib

3.1、代码的织入

3.1.1、织入时期
  • 编译期(AspectJ)
  • 类加载时(AspectJ 5+)
  • 运行时(Spring AOP)

3.2、代理模式

3.2.1、静态代理
调用被代理的对象(Target)的目标方法的客户端(Caller)通过代理类(Proxy)间接与被代理的对象(Target)进行通讯。
客户端(Caller)通过接口调用目标方法,而代理类(Proxy)收到客户端发来的请求时会把真正的执行交给被代理的类(Target),而代理类可以在目标方法执行前后执行其他的方法。

3.2.2、动态代理
|——>基于接口的(JDK方式)
实现方式——> |
|——>基于继承的(cglib)

  • JDK代理:代理类要实现InvocationHandler接口,且只能基于接口实现代理。
  • Cglib代理:代理类实现MethodInteceptor接口,通过继承方式实现代理,所以无法代理private和final以及static方法。

3.3、Spring对代理模式的选择

  • 如果目标对象实现了接口,则使用JDK代理
  • 如果目标对象没有实现接口,则使用Cglib代理
  • 如果目标对象实现了接口,但强制使用Cglib,则使用Cglib代理

Spring AOP(面向切面编程)是Spring框架中的一个模块,用于提供横切关注点(Cross-Cutting Concerns)的支持。横切关注点是与应用程序的核心业务逻辑无关的功能,例如日志记录、性能统计、事务管理等。 在Spring AOP中,通过定义切面(Aspect)来捕获横切关注点,并将其应用到目标对象的方法中。切面由切点(Pointcut)和通知(Advice)组成。切点定义了在何处应用通知,通知则定义了在切点处执行的操作。 Spring AOP支持以下几种类型的通知: 1. 前置通知(Before Advice):在目标方法执行之前执行的通知。 2. 后置通知(After Advice):在目标方法执行之后执行的通知,不管方法是否抛出异常。 3. 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行的通知。 4. 异常通知(After Throwing Advice):在目标方法抛出异常后执行的通知。 5. 环绕通知(Around Advice):围绕目标方法执行的通知,可以在方法调用前后执行自定义操作。 除了通知,Spring AOP还支持引入(Introduction)和切点表达式(Pointcut Expression)等功能。引入允许为目标对象添加新的接口和实现,而切点表达式则允许开发人员定义切点的匹配规则。 要在Spring应用程序中使用AOP,需要进行以下步骤: 1. 引入Spring AOP的依赖。 2. 配置AOP代理。 3. 定义切面和通知。 4. 配置切点和通知之间的关系。 总之,Spring AOP提供了一种便捷的方式来处理横切关注点,使得开发人员可以将关注点与核心业务逻辑分离,提高代码的可维护性和可重用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值