Spring AOP 实战指南:从入门到精通(3)

米饭8个月前行业资讯447

3.3 @PointCut:

Spring 提供了 @PointCut 注解,把公共的切点表达式提取出来,需要用到时引用该切入点表达式即可,便于后续代码的维护。

@Aspect
@Slf4j
@Component
public class TestAspect {
    @Pointcut("execution(* com.example.demo.controller.*.*(..))")
    public void pt(){}
    @Around("pt()")
    public Object demo(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("方法执行前执行");
        Object result = joinPoint.proceed();
        log.info("方法执行后执行");
        return result;
    }
}

当切点定义使用 private 修饰时,仅能在当前切面类中使用,当其他切面类也要使用当前切点定义时,就需要把 private 改为 public。引用方式为:全限定类名.方法名()。

@Slf4j
@Component
@Aspect
public class TestAspect2 {
    @Before("com.example.demo.aspect.TestAspect.pt()")
    public void doBefore() {
        log.info("执⾏ TestAspect2 -> Before ⽅法");
    }
}

3.4 切面优先级 @Order:

当我们在一个项目中,定义了多个切面类时,并且这些切面类的多个切入点都匹配到了同一个目标方法。当目标方法运行的时候,这些切面类中的通知方法都会执行,那么这几个通知方法的执行顺序是什么样的呢?

我们通过程序来进行验证。

@Slf4j
@Component
@Aspect
public class TestAspect2 {
    @Pointcut("execution(* com.example.demo.controller.*.*(..))")
    private void pt(){}
    //前置通知
    @Before("pt()")
    public void doBefore() {
        log.info("执行 TestAspect2 -> Before 方法");
    }
    //后置通知
    @After("pt()")
    public void doAfter() {
        log.info("执行 TestAspect2 -> After 方法");
    }
}

@Aspect
@Component
@Slf4j
public class TestAspect3 {
    @Pointcut("execution(* com.example.demo.controller.*.*(..))")
    private void pt(){}
    //前置通知
    @Before("pt()")
    public void doBefore() {
        log.info("执行 TestAspect3 -> Before 方法");
    }
    //后置通知
    @After("pt()")
    public void doAfter() {
        log.info("执行 TestAspect3 -> After 方法");
    }
}

@Aspect
@Component
@Slf4j
public class TestAspect4 {
    @Pointcut("execution(* com.example.demo.controller.*.*(..))")
    private void pt(){}
    //前置通知
    @Before("pt()")
    public void doBefore() {
        log.info("执行 TestAspect4 -> Before 方法");
    }
    //后置通知
    @After("pt()")
    public void doAfter() {
        log.info("执行 TestAspect4 -> After 方法");
    }
}

运行上面程序:

cb19833aeabd9c7f63a21963145c3bf5.png

通过上述程序的运行结果,可以看出:


存在多个切面类时,默认按照切面类的类名字母排序:


@Before 通知:字母排名靠前的先执行。


@After 通知:字母排名靠前的后执行。


但这种方式不方便管理,我们的类名更多还是具备一定含义的。


Spring 给我们提供了一个新的注解,来控制这些切面通知的执行顺序:@Order。

@Slf4j
@Component
@Aspect
@Order(10)
public class TestAspect2 {
    //代码省略
}

@Aspect
@Component
@Slf4j
@Order(5)
public class TestAspect3 {
    //代码省略
}

@Aspect
@Component
@Slf4j
@Order(1)
public class TestAspect4 {
    //代码省略
}

运行程序:

36b3fca9c1995634a8524b640652fc6a.png

通过上述程序的运行结果,得出结论:

@Order 注解标识的切面类,执行顺序如下:

  • @Before 通知:数字越小先执行。

  • @After 通知:数字越大先执行。

@Order 的执行顺序可以抽象成下面这张图:

image-20241011084901893

本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!  

云掣基于多年在运维领域的丰富时间经验,编写了《云运维服务白皮书》,欢迎大家互相交流学习:

《云运维服务白皮书》下载地址:https://fs80.cn/v2kbbq

想了解更多大数据运维托管服务、数据库运维托管服务、应用系统运维托管服务的的客户,欢迎点击云掣官网沟通咨询:https://yunche.pro/?t=shequ


相关文章

Gartner权威报告解读|应用可观测性列为2023年重要战略技术趋势!

Gartner于今日发布企业机构在2023年需要探索的十大战略技术趋势。Gartner杰出研究副总裁Frances Karamouzis表示:“为了在经济动荡时期增加企业机构的盈利,首席信息官和IT高...

Linux 部署Java项目-jar包和war包(五)

Linux 部署Java项目-jar包和war包(五)

一、前景(jar包和war包区别)部署之前先说下两种包,java项目部署到服务器一般有用war包的,也有用jar包的,微服务spring-cloud普及后大部分打包都是jar,部署之前先搞清楚自己要打...

从传统运维到SRE的转型路线

从传统运维到SRE的转型路线

从传统运维向SRE(Site Reliability Engineering)转型需要技术技能、思维方式和工作模式的全面转变。以下是详细的转型路线图:一、理解SRE的核心理念SRE的定义SRE是Goo...

一文帮你理解整个SRE运维体系

一文帮你理解整个SRE运维体系

SRE运维体系的构建和工作职责划分。SRE工程师近年来的岗位需求逐年增加,被称为IT行业十大最受欢迎的行业之一。可观测性系统在任何有一定规模的企业内部,一旦推行起来整个SRE的运维模式,那么对于可观测...

【Docker】在 Ubuntu 上安装 Docker 的详细指南

【Docker】在 Ubuntu 上安装 Docker 的详细指南

Docker 是一个开源的平台,可以让开发者打包应用及其依赖项为一个可移植的容器。本文将详细介绍如何在 Ubuntu 上安装 Docker,包括安装步骤、常见命令以及一些注意事项。一、准备工...

JAVA 程序员-云计算学习路径

JAVA 程序员-云计算学习路径

课程内容关系图第一章:容器化基础云计算简单概念测试安装 Nginx服务器的安全组设置按量付费优点私有网络 VPC 实战Docker 基础概念开通华为服务器Docker 安装镜像操作容器操作修改容器内容...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。