欢迎关注方志朋的博客,回复”666“获面试宝典

来源:juejin.cn/post/7062506923194581029

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 应用。

因为本人经常手动去网上贴一些依赖导致,依赖冲突服务启动失败等一些问题。

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 大家有兴趣可以去看看。

public interface CalcService {public int div(int x, int y);
}

实现类

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

@Service
public class CalcServiceImpl implements CalcService {@Overridepublic 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 使用就三个步骤:

  • 定义 Aspect 定义切面

  • 定义 Pointcut 就是定义我们切入点

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

@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() 方法的代理失效。这个问题也是我们开发者在开发过程中最常遇到的一个问题。

@Service
public class AService {public void a() {System.out.println("...... a");b();}public void b() {System.out.println("...... b");}}
热门内容:
  • 面试官:private修饰的方法可以通过反射访问,那么private的意义是什么?

  • 最新 955 不加班的公司名单(2022版)

  • SpringCloud 微服务架构,适合接私活(附源码)

  • 一款基于 Spring Boot 的现代化社区

  • Spring Boot 3.0 M1 发布,正式弃用 Java 8,最低要求 Java 17。。。

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

Spring Aop 常见注解和执行顺序相关推荐

  1. Spring AOP之通知类别执行顺序

    以下内容来源:https://jinnianshilongnian.iteye.com/blog/1423489 如果我们有多个通知想要在同一连接点执行,那执行顺序如何确定呢?Spring AOP使用 ...

  2. spring AOP自定义注解方式实现日志管理

    转:spring AOP自定义注解方式实现日志管理 今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接 ...

  3. java @around,Spring AOP基于注解的Around通知

    是一种建议类型,可确保方法执行前后的通知可以运行. 以下是通知的语法: 语法 @Pointcut("execution(* com.yiibai.Student.getAge(..))&qu ...

  4. spring aop 自定义注解配合swagger注解保存操作日志到mysql数据库含(源码)

    spring aop 自定义注解保存操作日志到mysql数据库 一.思路 二.自定义注解 三.编写操作日志 四.编写操作日志切面\增强 五.使用 六.`注意` 一.思路 利用spring aop 对方 ...

  5. java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口

    前言 Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先 ...

  6. spring aop 配置注解 切入点说明

    转载链接:https://www.cnblogs.com/junzi2099/p/8274813.html 基于注解的Spring AOP开发 简单案例快速入门 定义目标类接口和实现类 /*** Cr ...

  7. Spring Boot相关知识(二) Spring Boot项目启动的执行顺序和原理

    2019独角兽企业重金招聘Python工程师标准>>> 1. 环境,程序入口 @SpringBootApplication public class Application {pub ...

  8. Spring AOP自定义注解并获取注解的参数

    环境 springboot:1.5 Intellij IDEA:2021.1 序言 最近有个需求,要做方法层面的权限控制.以前在公司使用的是spring security,然后使用注解 如下: @Pr ...

  9. java 静态代码块和spring @value注解注入执行顺序

    https://blog.csdn.net/evo_steven/article/details/86005965

最新文章

  1. 低代码、无代码?深度解读硅谷新趋势
  2. C# String部分方法的例子StringBuilder的简单介绍
  3. MapReduce基础开发之六Map多输入
  4. 详解X-shell7的安装与配置
  5. vs及番茄助手快捷键使用介绍
  6. 牛客题霸 [二叉树的镜像]C++题解/答案
  7. java泛型程序设计——调用遗留代码
  8. TOP互联网公司都在用,为什么SRE比传统运维更抢手?
  9. Xcode 指定测试设备打包IPA
  10. vue中的组件重定向
  11. Oracle Telnet 1521 失败
  12. STM32学习笔记(正点原子STM32Mini版)
  13. 微信的自动回复接入聊天机器人
  14. MAC电脑触摸板手势(提高办公效率)
  15. python续行_python的续行
  16. python start方法_进程方法 run和start的区别
  17. 程序人生-hello`s P2P
  18. PR2019中对基本图形mogrt文件进行文件夹分类不再混乱
  19. 锁存器,D触发器和寄存器的关系与区别
  20. 【个人网站搭建】GitHub pages+hexo框架下为next主题添加分类及标签

热门文章

  1. C++条件变量使用详解
  2. 关于Linux服务器磁盘空间占满问题的解决方法
  3. top命令详解-性能分析
  4. eclipse启动时报错An internal error occurred during: Initializing Java Tooling.
  5. WebKit、Gecko使用图形库
  6. 高手讲解PHP遍历数组的方法
  7. LeetCode实战:螺旋矩阵 II
  8. 如何利用遗传算法进行自变量降维
  9. Matlab与线性代数 -- 稀疏矩阵的创建
  10. 求两个矩形重叠部分的面积