基于注解的Spring AOP
Posted 天河一粟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于注解的Spring AOP相关的知识,希望对你有一定的参考价值。
基于注解的Spring AOP
-
常用的注解
注解 解释 @Before 该通知方法会在目标方法执行之前执行 @AfterReturning 该通知方法会在目标方法执行完返回后执行 @After 该通知方法会在目标方法返回或 抛出异常
后执行@Around 该通知方法将目标方法封装起来,环绕通知 @AfterThrowing 该通知方法会在目标方法抛出异常后执行 @Pointcut 通用切入点 -
@Pointcut
之execution
语法execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?)
带有?的模式可以省略掉
多种语法可以使用&&、 ||、 !
连接 -
@Pointcut
之其它语法语法 解释 execution 用于匹配方法执行的连接点 within 用于匹配指定类型内的方法执行 this 用于匹配当前AOP代理对象类型的执行方法 args 用于匹配当前执行的方法传入的参数为指定类型的执行方法 @within 用于匹配所有持有指定注解类型类的方法(注解在类上) @annotation 用于匹配当前执行方法持有指定注解的方法(注解在方法上) -
代码示例
完整代码示例package sky.jin.aspect.aspect; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import sky.jin.aspect.annotaion.UnknownException; /** * 切面 * * @author sky.jin * @date 2022/2/7 15:35 */ @Slf4j @Aspect @Component public class MyAspect /** * execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) * * - execution:用于匹配方法执行的连接点; * - within:用于匹配指定类型内的方法执行; * - this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口类型匹配; * - target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口类型匹配; * - args:用于匹配当前执行的方法传入的参数为指定类型的执行方法; * - @within:用于匹配所以持有指定注解类型内的方法; * - @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解; * - @args:用于匹配当前执行的方法传入的参数持有指定注解的执行; * - @annotation:用于匹配当前执行方法持有指定注解的方法; * */ // 组合方式 &&、 ||、 ! // 指定 aspect 包和子包的任意方法的执行 // @Pointcut(value = "execution(* sky.jin.aspect..*(..))") // 任意公共方法的执行 // @Pointcut(value = "execution(public * sky.jin.aspect..*(..))") // 任何一个以“queryNameBy”开始的方法的执行 // @Pointcut(value = "execution(* queryNameBy*(..))") // 指定 AspectService 接口的任意方法的执行 // @Pointcut(value = "execution(* sky..aspect.service.AspectService.*(..))") // 指定 service 包任意类方法的执行 // @Pointcut(value = "execution(* sky..aspect.service.*(..))") // 指定 service 包和子包任意类方法的执行 // @Pointcut(value = "execution(* sky..aspect.service..*(..))") // 指定 controller 包任意类方法的执行 // @Pointcut(value = "within(sky.jin.aspect.controller.*)") // 指定 aspect 包和子包任意类方法的执行 // @Pointcut(value = "within(sky.jin.aspect..*)") // 实现了AspectController接口的所有类,如果AspectController不是接口,限定AspectController单个类 // @Pointcut(value = "this(sky.jin.aspect.controller.AspectController)") // 实现了AspectService接口的所有类,如果AspectService不是接口,限定SAspectService单个类 // @Pointcut(value = "this(sky.jin.aspect.service.AspectService)") // 带有@UnknownException注解的所有类的任意方法 // @Pointcut(value = "@within(sky.jin.aspect.annotaion.UnknownException)") // 带有@UnknownException注解的所有类的任意方法 ×(没有调通) // @Pointcut(value = "@target(sky.jin.aspect.annotaion.UnknownException)") // 带有@UnknownException注解的任意方法 // @Pointcut(value = "@annotation(sky.jin.aspect.annotaion.UnknownException)") // 参数带有@PathVariable注解的任意方法 ×(没有调通) // @Pointcut(value = "@args(org.springframework.web.bind.annotation.PathVariable)") @Pointcut(value = "within(sky.jin.aspect..*) && args(Long, ..)") // 参数为String类型(运行时决定)的方法 public void point() /** * 该通知方法会在目标方法执行之前执行 */ @Before(value = "point()", argNames = "jp") public void before(JoinPoint jp) log.info("===> 前置通知 MyAfterThrowing before jp = params = ", jp, jp.getArgs()); /** * 该通知方法会在目标方法执行完返回后执行 */ @AfterReturning("point()") public void afterReturning(JoinPoint jp) log.info("===> 后置通知 MyAfterThrowing afterReturning jp = params = ", jp, jp.getArgs()); /** * 通知方法会在目标方法返回或抛出异常后执行 */ @After("point()") public void after(JoinPoint jp) log.info("===> 后置或异常通知 MyAfterThrowing after jp = ", jp); /** * 该通知方法将目标方法封装起来,环绕通知 */ @Around(value = "point()", argNames = "jp") public Object around(ProceedingJoinPoint jp) throws Throwable log.info("===> 环绕通知开始 MyAfterThrowing around begin jp = ", jp); Object proceed = jp.proceed(); log.info("===> 环绕通知结束 MyAfterThrowing around end jp = ", jp); return proceed; /** * 该通知方法会在目标方法抛出异常后执行 * - @annotation:用于匹配当前执行方法持有指定注解的方法 */ @AfterThrowing(throwing = "e", pointcut = "@annotation(unknownException)") public void afterThrowing_annotation(JoinPoint jp, Throwable e, UnknownException unknownException) log.info("===> 异常通知 MyAfterThrowing afterThrowing_annotation jp = unknownException = ", jp, unknownException); /** * 该通知方法会在目标方法抛出异常后执行 */ @AfterThrowing(throwing = "e", pointcut = "point()") public void AfterThrowing(JoinPoint jp, Throwable e) log.info("===> 异常通知 MyAfterThrowing AfterThrowing jp = ", jp);
以上是关于基于注解的Spring AOP的主要内容,如果未能解决你的问题,请参考以下文章