Spring Aop 常见注解和执行顺序

SpringAOP执行顺序 Spring中的Advisors的执行顺序 阅读详情

欢迎关注方志朋的博客,回复”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 {

    @Override
    public int div(int x, int y) {
        int result = x / y;
        System.out.println("====> CalcServiceImpl 被调用了,我们的计算结果是:" + result);
        return result;
    }
}

aop 拦截器

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

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

9d96f8c3f369f3ac5b917dea147b7c31.png

这里面根本就没有 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 方法把:如下所示:

9362b138336e8dcaf04d57bbb60f1b1e.png

执行结论

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

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

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

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

08b03d7e8da249e709b018b2790afab3.png

多切面的情况

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

d23f1182ca8c418b76a1de858a81b627.png

代理失效场景

下面一种场景会导致 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");
    }

}
热门内容:

56ec7636a6c324796b605403c8886fc1.png


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

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

数电-基于FPGA的自动售货控制系统设计 本次数电的课程设计是设计一款基于FPGA的自动售货控制系统,因为手上暂时没有FPGA的板子,所以先采用proteus仿真进行设计,观察系统效果,等之后FPGA板子下发,再移到quartus上调试下载。同样是自己第一次自主设计电路系统,可能在功能上不完整或者逻辑上有错误,大家多多包涵,欢迎沟通交流。 阅读详情

相关推荐

从轴承润滑到代码实现:手把手教你用Python FDM求解稳态雷诺方程

本文详细介绍了如何用Python FDM(有限差分法)求解稳态雷诺方程,从轴承润滑理论到代码实现的全过程。通过构建无量纲方程、有限差分格式迭代求解算法,开发者可以快速实现专业级润滑分析,应用于涡轮发电机、汽车曲轴等场景。文章还提供了完整的Python代码示例结果可视化方法,帮助工程师优化轴承设计。

weixin_28689507的博客 95

Spring Aop的使用通知注解执行顺序

一、Aop 常用注解 @Before 前置通知: 目标方法之前执行 @After 后置通知: 目标方法之后执行(始终执行) @AfterReturning 返回后通知: 执行方法结束前执行(异常不执行) @AfterThrowing 异常通知: 出现异常时候执行 @Around 环绕通知: 环绕目标方法执行 spring4spring5的全部通知执行顺序是不同的,下面用案例说明。 二、案例演示 2.1 业务类 创建业务接口类:CalcService /** * @InterfaceName CalS

weixin_41979002的博客 2417

有了网段为什么还要有VLAN???

近几日,在学习VLAN及VXLAN方面的知识,对于产生原因做一个总结及详解。 VLAN(Virtual Local Area Network,虚拟局域网),其主要用途是用来缩小广播域,即进行隔离。 先对广播域的一个概念做如下描绘:如下图,主机A、B、C、D均连接在交换机SW1上,其中A、C同网段为192.168.252网段,而BD同网段,为192.168.250网段。 现,假如A与C第...

dandandean_96的博客 6851

Spring Aop通知注解执行顺序

Spring Aop通知注解执行顺序

weixin_57869541的博客 416

[Spring] Aop 注解执行顺序

验证 @Around、@Before、@After、@AfterReturning、@AfterThrowing 执行顺序

qq_40155680的博客 1056

SpringAOP的通知类型执行顺序

@Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行 @Before:前置通知,此注解标注的通知方法在目标方法前被执行 @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行 @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行 @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行

weixin_46665411的博客 1505

Spring AOP 常见注解执行顺序

大家好,我是DD。我一直强调基础很重要!而现在我们通常直接学Spring BootSpring Cloud之后,有不少小伙伴对于Spring AOP的了解就不那么充分了!所以,今天转了一...

程序猿DD 916

面试官:Spring Aop 常见注解执行顺序

如果目标对象实现了接口,则默认采用JDK动态代理如果目标对象没有实现接口,则采用进行动态代理如果目标对象实现了接口,且强制Cglib,则使用cglib代理这块的逻辑在大家有兴趣可以去看看。}实现类这里我门就简单一点做一个除法操作,可以模拟正常也可以很容易的模拟错误。@Service@OverrideSystem.out.println("====> CalcServiceImpl 被调用了,我们的计算结果是:" + result);}}aop 拦截器。

m0_73311735的博客 762

SpringBoot应用AOP及各注解执行顺序 统一AOP切面

SpringBoot应用AOP及各注解执行顺序 统一AOP切面

qq_35572020的博客 1643

Spring AOP相关注解执行顺序

用于标识一个类是切面的注解。通常与其他通知注解一起使用,定义切面类。: 注解来定义切点,它用于描述哪些连接点将会被通知所通知。

共同学习,共同成长! 944

Spring AOP @Before @Around @After 等 advice 的执行顺序 侵立删

转自:https://blog.csdn.net/rainbow702/article/details/52185827   用过spring框架进行开发的人,多多少少会使用过它的AOP功能,都知道有@Before、@Around@After等advice。最近,为了实现项目中的输出日志权限控制这两个需求,我也使用到了AOP功能。我使用到了@Before、@Around这两个advice。...

心神沫沫的收藏 552

Spring Boot Aop 执行顺序

spring boot 项目中,使用 aop 增强,不仅可以很优雅地扩展功能,还可以让一写多用,避免写重复代码,例如:记录接口耗时,记录接口日志,接口权限,等等。然而,当我们在一个接口中使用多个 aop,时,就需要注意他们的执行顺序了。如果不把这个问题搞明白,那我们的程序就不可控,这是不允许的,这就是我们今天要讨论的问题。因为我们用的是 Around,先进入Aop1,再进入到aop2,然后执行api,执行完以后,再返回到 aop2,最后返回aop1。这样,我们也就通过使用包扫描的方式实现了 AOP

冯文议技术博客 1917

面试官:Spring AOP的通知注解有哪些?它们的执行顺序是什么?

Aspect@ComponentSystem.out.println("@Around开始");System.out.println("@Around结束");通知类型:5种注解覆盖方法执行全生命周期。执行顺序@Around包裹所有通知,@After类似finally始终执行。源码逻辑:通过拦截器链按顺序触发通知。

Like0703的博客 1488

spring多个AOP执行先后顺序记录

spring多个AOP执行先后顺序记录 order越小越是最先执行,最先执行的最后结束。

前端kk的博客 6163

PSIM BOOST PFC仿真

PSIM BOOST PFC(Power Factor Correction)仿真是一种基于PSIM软件的电力电子仿真,用于模拟分析Boost PFC电路的性能。Boost PFC电路是一种常见的电源转换器,主要用于提高电源系统的功率因数,减小谐波失真,提高电能利用效率。在进行PSIM BOOST PFC仿真时,首先需要建立Boost PFC电路模型。这个模型包括输入电源、开关管、二极管、电感、电容等元件。接下来,设置仿真参数,如输入电压、输出电压、开关频率、负载等。然后,运行仿真,观察电路的工作状态性能指标,如输入电流、输出电压、功率因数、总谐波失真等。通过PSIM BOOST PFC仿真,可以对Boost PFC电路进行详细的分析优化。例如,可以通过调整开关频率电感值来减小输入电流的纹波;通过选择合适的开关管二极管来降低导通损耗开关损耗;通过优化控制策略来提高功率因数减小总谐波失真。这些分析优化可以帮助设计出更高效、更可靠的Boost PFC电路。总之,PSIM BOOST PFC仿真是一种有效的工具,可以帮助工程师们更好地理解设计Boost PFC电

改进YOLOv8s算法在桥梁裂缝检测中的应用与轻量化策略.docx

改进YOLOv8s算法在桥梁裂缝检测中的应用与轻量化策略.docx

上一篇: 要写好业务代码,也没这么简单!
下一篇: JetBrains 宣布:IntelliJ 平台彻底停用 Log4j 组件,建议切换至 java.util.logging
公众号:方志朋
博客等级 码龄5年 307粉丝 94原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值