广告位联系
返回顶部
分享到

Spring Aop常见注解与执行顺序

java 来源:互联网 作者:秩名 发布时间:2022-02-09 19:39:20 人浏览
摘要

Spring 一开始最强大的就是 IOC / AOP 两大核心功能,我们今天一起来学习一下 Spring AOP 常见注解和执行顺序。 Spring Aop 的常用注解 首先我们一起来回顾一下 Spring Aop 中常用的几个注解:

Spring 一开始最强大的就是 IOC / AOP 两大核心功能,我们今天一起来学习一下 Spring AOP 常见注解和执行顺序。

 

Spring Aop 的常用注解

首先我们一起来回顾一下 Spring Aop 中常用的几个注解:

  • @Before 前置通知:目标方法之前执行
  • @After 后置通知:目标方法之后执行(始终执行)
  • @AfterReturning 返回之后通知:执行方法结束之前执行(异常不执行)
  • @AfterThrowing 异常通知:出香异常后执行
  • @Around 环绕通知:环绕目标方法执行

 

常见问题

1、你肯定知道 Spring , 那说说 Aop 的去全部通知顺序, Spring Boot 或者 Spring Boot 2 对 aop 的执行顺序影响?

2、说说你在 AOP 中遇到的那些坑?

 

示例代码

下面我们先快速构建一个 spring aop 的 demo 程序来一起讨论 spring aop 中的一些细节。

 

配置文件

为了方便我直接使用 spring-boot 进行快速的项目搭建,大家可以使用 idea 的spring-boot 项目快速创建功能,或者去 start.spring.io 上面去快速创建spring-boot 应用。(因为本人经常手动去网上贴一些依赖导致,依赖冲突服务启动失败等一些问题)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

plugins {

    id 'org.springframework.boot' version '2.6.3'

    id 'io.spring.dependency-management' version '1.0.11.RELEASE'

    id 'java'

}

 

group 'io.zhengsh'

version '1.0-SNAPSHOT'

 

repositories {

    mavenCentral()

    maven { url 'https://repo.spring.io/milestone' }

    maven { url 'https://repo.spring.io/snapshot' }

}

 

dependencies {

    # 其实这里也可以不增加 web 配置,为了试验简单,大家请忽略

    implementation 'org.springframework.boot:spring-boot-starter-web'

    implementation 'org.springframework.boot:spring-boot-starter-actuator'

    implementation 'org.springframework.boot:spring-boot-starter-aop'

     

    testImplementation 'org.springframework.boot:spring-boot-starter-test'

}

 

tasks.named('test') {

    useJUnitPlatform()

}

 

接口类

首先我们需要定义一个接口。我们这里可以再来回顾一下 JDK 的默认代理实现的选择:

如果目标对象实现了接口,则默认采用JDK动态代理
如果目标对象没有实现接口,则采用进行动态代理
如果目标对象实现了接口,且强制Cglib,则使用cglib代理

这块的逻辑在 DefaultAopProxyFactory 大家有兴趣可以去看看。

1

2

3

public interface CalcService {

    public int div(int x, int y);

}

 

实现类

这里我门就简单一点做一个除法操作,可以模拟正常也可以很容易的模拟错误。

1

2

3

4

5

6

7

8

9

@Service

public class CalcServiceImpl implements CalcService {

    @Override

    public int div(int x, int y) {

        int result = x / y;

        System.out.println("====> CalcServiceImpl 被调用了,我们的计算结果是:" + result);

        return result;

    }

}

 

aop 拦截器

申明一个拦截器我们要为当前对象增加 @Aspect 和 @Component ,笔者之前也是才踩过这样的坑,只加了一个。

其实这块我刚开始也不是很理解,但是我看了 Aspect 注解的定义我就清楚了

这里面根本就没有 Bean 的定义。所以我们还是乖乖的加上两个注解。 还有就是如果当测试的时候需要开启Aop 的支持为配置类上增加 @EnableAspectJAutoProxy 注解。

其实 Aop 使用就三个步骤:

1、定义 Aspect 定义切面

2、定义 Pointcut 就是定义我们切入点

3、定义具体的通知,比如: @After, @Before 等。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

@Aspect

@Component

public class MyAspect {

 

    @Pointcut("execution(* io.zhengsh.spring.service.impl..*.*(..))")

    public void divPointCut() {

 

    }

 

    @Before("divPointCut()")

    public void beforeNotify() {

        System.out.println("----===>> @Before 我是前置通知");

    }

 

    @After("divPointCut")

    public void afterNotify() {

        System.out.println("----===>> @After  我是后置通知");

    }

 

    @AfterReturning("divPointCut")

    public void afterReturningNotify() {

        System.out.println("----===>> @AfterReturning 我是前置通知");

    }

 

    @AfterThrowing("divPointCut")

    public void afterThrowingNotify() {

        System.out.println("----===>> @AfterThrowing 我是异常通知");

    }

 

    @Around("divPointCut")

    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object retVal;

        System.out.println("----===>> @Around 环绕通知之前 AAA");

        retVal = proceedingJoinPoint.proceed();

        System.out.println("----===>> @Around 环绕通知之后 BBB");

        return retVal;

    }

}

 

测试类

其实我这个测试类,虽然用了 @Test 注解,但是我这个类更加像一个 main 方法把:如下所示:

 

执行结论

结果记录:spring 4.x, spring-boot 1.5.9

无法现在依赖,所以无法试验

我直接说一下结论: Spring 4 中环绕通知是在最里面执行的

结果记录:spring 版本5.3.15 springboot 版本2.6.3

 

多切面的情况

多个切面的情况下,可以通过@Order指定先后顺序,数字越小,优先级越高。 如下图所示:

 

代理失效场景

下面一种场景会导致 aop 代理失效,因为我们在执行 a 方法的时候其实本质是执行 AServer#a 的方法拦截器(MethodInterceptor)链, 当我们在 a 方法内直接执行b(), 其实本质就相当于 this.b() , 这个时候由执行 a方法是调用到 a 的原始对象相当于是 this 调用,那么会导致 b() 方法的代理失效。这个问题也是我们开发者在开发过程中最常遇到的一个问题。

1

2

3

4

5

6

7

8

9

10

11

12

13

@Service

public class AService {

     

    public void a() {

        System.out.println("...... a");

        b();

    }

     

    public void b() {

        System.out.println("...... b");

    }

 

}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7062506923194581029
相关文章
  • SpringBoot自定义错误处理逻辑介绍

    SpringBoot自定义错误处理逻辑介绍
    1. 自定义错误页面 将自定义错误页面放在 templates 的 error 文件夹下,SpringBoot 精确匹配错误信息,使用 4xx.html 或者 5xx.html 页面可以打印错误
  • Java实现手写一个线程池的代码

    Java实现手写一个线程池的代码
    线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和
  • Java实现断点续传功能的代码

    Java实现断点续传功能的代码
    题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节
  • 你可知HashMap为什么是线程不安全的
    HashMap 的线程不安全 HashMap 的线程不安全主要体现在下面两个方面 在 jdk 1.7 中,当并发执行扩容操作时会造成环形链和数据丢失的情况 在
  • ArrayList的动态扩容机制的介绍

    ArrayList的动态扩容机制的介绍
    对于 ArrayList 的动态扩容机制想必大家都听说过,之前的文章中也谈到过,不过由于时间久远,早已忘却。 所以利用这篇文章做做笔记,加
  • JVM基础之字节码的增强技术介绍

    JVM基础之字节码的增强技术介绍
    字节码增强技术 在上文中,着重介绍了字节码的结构,这为我们了解字节码增强技术的实现打下了基础。字节码增强技术就是一类对现有字
  • Java中的字节码增强技术

    Java中的字节码增强技术
    1.字节码增强技术 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。 参考地址 2.常见技术 技术分类 类
  • Redis BloomFilter布隆过滤器原理与实现

    Redis BloomFilter布隆过滤器原理与实现
    Bloom Filter 概念 布隆过滤器(英语:Bloom Filter)是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射
  • Java C++算法题解leetcode801使序列递增的最小交换次

    Java C++算法题解leetcode801使序列递增的最小交换次
    题目要求 思路:状态机DP 实现一:状态机 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minSwap(int[] nums1, int[] nums2) { int n
  • Mybatis结果集映射与生命周期介绍

    Mybatis结果集映射与生命周期介绍
    一、ResultMap结果集映射 1、设计思想 对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了 2、resultMap的应用场
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计