Spring Aop 常见注解和执行顺序
欢迎关注方志朋的博客,回复”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 常见注解和执行顺序相关推荐
- Spring AOP之通知类别执行顺序
以下内容来源:https://jinnianshilongnian.iteye.com/blog/1423489 如果我们有多个通知想要在同一连接点执行,那执行顺序如何确定呢?Spring AOP使用 ...
- spring AOP自定义注解方式实现日志管理
转:spring AOP自定义注解方式实现日志管理 今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接 ...
- java @around,Spring AOP基于注解的Around通知
是一种建议类型,可确保方法执行前后的通知可以运行. 以下是通知的语法: 语法 @Pointcut("execution(* com.yiibai.Student.getAge(..))&qu ...
- spring aop 自定义注解配合swagger注解保存操作日志到mysql数据库含(源码)
spring aop 自定义注解保存操作日志到mysql数据库 一.思路 二.自定义注解 三.编写操作日志 四.编写操作日志切面\增强 五.使用 六.`注意` 一.思路 利用spring aop 对方 ...
- java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口
前言 Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先 ...
- spring aop 配置注解 切入点说明
转载链接:https://www.cnblogs.com/junzi2099/p/8274813.html 基于注解的Spring AOP开发 简单案例快速入门 定义目标类接口和实现类 /*** Cr ...
- Spring Boot相关知识(二) Spring Boot项目启动的执行顺序和原理
2019独角兽企业重金招聘Python工程师标准>>> 1. 环境,程序入口 @SpringBootApplication public class Application {pub ...
- Spring AOP自定义注解并获取注解的参数
环境 springboot:1.5 Intellij IDEA:2021.1 序言 最近有个需求,要做方法层面的权限控制.以前在公司使用的是spring security,然后使用注解 如下: @Pr ...
- java 静态代码块和spring @value注解注入执行顺序
https://blog.csdn.net/evo_steven/article/details/86005965
最新文章
- 低代码、无代码?深度解读硅谷新趋势
- C# String部分方法的例子StringBuilder的简单介绍
- MapReduce基础开发之六Map多输入
- 详解X-shell7的安装与配置
- vs及番茄助手快捷键使用介绍
- 牛客题霸 [二叉树的镜像]C++题解/答案
- java泛型程序设计——调用遗留代码
- TOP互联网公司都在用,为什么SRE比传统运维更抢手?
- Xcode 指定测试设备打包IPA
- vue中的组件重定向
- Oracle Telnet 1521 失败
- STM32学习笔记(正点原子STM32Mini版)
- 微信的自动回复接入聊天机器人
- MAC电脑触摸板手势(提高办公效率)
- python续行_python的续行
- python start方法_进程方法 run和start的区别
- 程序人生-hello`s P2P
- PR2019中对基本图形mogrt文件进行文件夹分类不再混乱
- 锁存器,D触发器和寄存器的关系与区别
- 【个人网站搭建】GitHub pages+hexo框架下为next主题添加分类及标签