Spring注解AOP中通知顺序颠倒的bug

Redis redis 阅读详情

记录在Spring框架有关注解AOP的学习过程中的遇到的一个bug:

首先是Project Structure:
在这里插入图片描述

配置文件bean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置Spring创建容器时要扫描的包 -->
    <context:component-scan base-package="wzc"></context:component-scan>

    <!-- 配置Spring开启注解AOP的支持 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

业务层Service实现类:

@Service("accountService")
public class AccountServiceImpl implements IAccountService {


    public void saveAccount() {
        System.out.println("执行了保存...");
//        int i = 1/0;
    }
}

工具类Logger:

@Component("logger")
@Aspect//表示当前类是一个切面类
public class Logger {

    @Pointcut("execution(* wzc.service.impl.*.*(..))")
    private void pt1(){}

    /**
     * 前置通知
     */
    @Before("pt1()")
    public void beforePrintLog(){
        System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了...");
    }

    /**
     * 后置通知
     */
    @AfterReturning("pt1()")
    public void afterReturningPrintLog(){
        System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了...");
    }

    /**
     * 异常通知
     */
    @AfterThrowing("pt1()")
    public void afterThrowingPrintLog(){
        System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了...");
    }

    /**
     * 最终通知
     */
    @After("pt1()")
    public void afterPrintLog(){
        System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了...");
    }
	
	/**
	* 环绕通知
	*/
    //    @Around("pt1()")
    public Object aroundPrintLog(ProceedingJoinPoint pjp){

        Object rtValue = null;
        try {
            Object[] args = pjp.getArgs();//得到方法执行所需的参数

            System.out.println("Logger类中的aroundPrintLog方法开始记录日志了...前置");

            rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)

            System.out.println("Logger类中的aroundPrintLog方法开始记录日志了...后置");
            return rtValue;
        } catch (Throwable t) {
            System.out.println("Logger类中的aroundPrintLog方法开始记录日志了...异常");
            throw new RuntimeException(t);
        }finally {
            System.out.println("Logger类中的aroundPrintLog方法开始记录日志了...最终");
        }
    }
}


测试类AOPTest:

public class AOPTest {
    public static void main(String[] args) {
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取对象
        IAccountService as = (IAccountService) ac.getBean("accountService");
        //3.执行方法
        as.saveAccount();

    }
}

我们知道,正常的通知顺序应该是:

  • 配置前置通知@Before: 在切入点方法执行之前执行
  • 配置后置通知@AfterReturning: 在切入点方法正常执行之后执行. 它和异常通知永远只能执行一个
  • 配置异常通知@AfterThrowing:在切入点方法执行产生异常之后执行. 它和后置通知永远只能执行一个
  • 配置最终通知@After: 无论切入点方法是否正常执行,它都会在其后面执行
  • 配置环绕通知@Around: 可以在代码中手动控制增强方法何时执行

使用注解配置通知时,产生后置通知与最终通知顺序颠倒的现象.
在这里插入图片描述

而使用环绕通知的方式则通知顺序正常
在这里插入图片描述
把Service实现类中的数学异常注释放开,执行结果也相同:即发生异常通知与最终通知顺序颠倒的现象

结论:Spring基于注解的AOP中, 这4个通知的执行调用顺序确实存在问题.因此,在我们的实际开发中,应该慎重考虑.
解决方案:

  1. 使用纯xml配置文件代替注解方式进行配置
  2. 在使用注解方式的前提下, 建议使用没有顺序问题的环绕通知. 此问题的原理待深入学习后再来填坑.
机器学习第五章之决策树模型 机器学习专题系列 阅读详情

相关推荐

PLC作为Modbus TCP客户端

PLC作为Modbus TCP客户端,Modbus Slave作为服务器

soledad_chao的博客 4378

SpringAOP中通知顺序颠倒的bug

今天在学习通过注解来实现AOP功能发现了一个bug,就是后置通知和最终通知的顺序与xml配置下实现AOP功能的顺序有些出入 先记录下这几个通知类型并解释其意义 1、前置通知 在目标方法前执行 无论目标方法是否抛出异常,都执行,因为在执行前置通知的时候,目标方法还没有执行,还没有遇到异常 2、后置通知 在目标方法执行之后执行 当目标方法遇到异常,后置通知将不再执行 后置通知可以接受目标方法的返...

MarkusZhang的博客 1404

服务器能效测试工具BenchSEE使用方法简介

BenchSEE是由中国标准化研究院开发的一款针对服务器产品能效测试的基准软件。BenchSEE基准的设计参考了全球众多服务器厂家、芯片厂家、能效认证机构和IT节能领域科研机构的意见,旨在满足服务器市场应用对能效测评的需求。BenchSEE基准负载工具支持的服务器类型包括:机架服务器、刀片服务器多节点服务器和机柜服务器等,服务器可以配的最大外理器个数包括:1P,2P和4P等。测试基准涵盖服务器关键部件:CPU,内存和存储介质三大基础部件。

MQWYY3的博客 4216

spring4到spring5 AOP执行顺序的转变

前言:之前听尚硅谷周阳阳哥讲课,说是spring5的aop执行顺序和spring4不一样了,并且选用了springboot2.3.10版本测试,结果确实变化了。但是,本人亲自测试以后发现自己使用的springboot2.2.2顺序并没有发生变化,为了弄清楚原因,特意查了下资料和官网,经过代码测试最后得出结果如下: 从spring 5.2.7.RELEASE开始(包括5.2.7),spring aop的执行顺序发生了变化。 测试代码: public interface CommonService {

b13001216978的博客 1775

用Python实现单层感知器:5分钟搞定逻辑与/或/异或分类(附避坑指南)

本文通过Python代码实战,详细讲解了单层感知器的核心原理与实现步骤,5分钟内即可完成逻辑与、或运算的分类任务。文章深入剖析了单层感知器的能力边界,解释了其无法解决异或(XOR)等线性不可分问题的根本原因,并提供了学习率设置、权重初始化等关键避坑指南,帮助初学者直观理解神经网络的基础。

ttt77的博客 1084

深度学习模型设计的方法和技巧

设计神经网络模型是一个迭代的过程,需要不断试验和调整各个组成部分,以达到最佳性能。同时,遵循良好的工程实践,如模块化设计、版本控制、文档记录等,也是成功的关键。

xw555666的博客 4026

Spring中AOP注解的使用说明及通知的执行顺序问题

步骤: 1.环境搭建:项目结构 com |_ xiaozhang |_ service ...

Java全栈领域/离线地图/微服务 7956

STM32开发工具链选型:MDK、CubeIDE、VSCode与IAR深度对比

嵌入式开发工具链是连接软件逻辑与硬件行为的核心枢纽,其选择直接影响代码可靠性、调试效率与量产稳定性。从编译器优化能力、调试协议支持(如ARM CoreSight、SWO)、硬件抽象层级(寄存器/LL/HAL)到跨平台构建能力,不同工具在实时性保障、静态分析合规性(如MISRA-C)、WCET可预测性及生态开放度上存在本质差异。尤其在STM32平台,Keil MDK凭借深度调试能力成为HardFault定位首选,STM32CubeIDE依托图形化配置加速外设初始化,而VSCode+PlatformIO则以LS

weixin_42602368的博客 429

Spring AOP

Aspect //定义切面@Component//切点(配置拦截规则)}}对上面代码的解释:@Aspect这个注解表示这个类是一个AOP类,也就是说这个类是一个切面;@Component这个注解表示组件,当我们不知道具体该给某个类使用那个注解来注入到Spring框架时,我们就可以使用@Component这个注解;@Pointcut这个注解表示该方法是一个切点,它后面跟的是AspectJ表达式(切点表达式)。

yahid的博客 1232

保姆级教程:用BIGEMAP和Global Mapper搞定5米精度DEM高程数据下载与处理

本文提供了一份详细的5米精度DEM高程数据处理教程,涵盖从BIGEMAP下载到Global Mapper处理的完整流程。通过实战案例和避坑指南,帮助用户掌握高效下载DEM数据、优化等高线生成及坐标系转换的关键技巧,适用于GIS新手和专业人士。

weixin_34169322的博客 390

提取游戏音频文件.bnk

bnk其实是一种对音频的加密方式,一个.bnk文件中通常包含了多个语音文件,一般可以使用Wwise-Unpacker来解码.bnk格式文件该工具命名没有规律,需要手动整理文件名。市面上很多的游戏都把音频文件打成.bnk文件(比如永劫无间),用这种方式可以将你想要的游戏的音频都提取出来,本文内容仅供自己娱乐。

类人_猿的博客 8745

关于Spring 基于注解的AOP通知执行顺序

网上的一些教程,大多数是拿Spring4.x 跟5.x来对比,其实 这几个通知顺序是从Spring版本为5.2.7.RELEASE---SpringBoot版本为2.2.8.RELEASE时 AOP执行顺序才发生的改变。 Aop常用注解 @Before 前置通知:目标方法之前执行 @After 后置通知:目标方法之后执行(始终执行) @AfterReturning 返回后通知,执行方法结束前执行执行(异常不执行) @AfterThrowing 异常通知:出现异常时执行 @Around 环绕通知

子游丶 422

微信小程序 “net::ERR_CONNECTION_REFUSED” 报错大揭秘与破解之道

在微信小程序开发与运行过程中,“net::ERR_CONNECTION_REFUSED” 报错是开发者常遇难题。该错误意味着小程序与服务器连接建立失败,会导致功能无法使用、数据加载异常等问题,严重影响用户体验和业务运转。本文系统剖析此错误,从网络环境不佳、服务器异常、小程序配置有误等常见触发场景入手,提供网络、服务器、配置、代码等多维度排查步骤,给出针对性解决策略,如修复网络、处理服务器故障、修正配置与代码错误,还提出开发与运维阶段的预防措施,助力开发者高效解决该报错问题。

邓邓子的博客 6132

idea__Spring5框架17——基于注解的AOP实现事务控制及问题分析

低版本的spring基于aop注解事务管理的顺序是有bug的,先执行最终再执行后置通知,之前说过了 环绕通知的方法可以解决 这个问题是由于5.0.2版本后置通知和最终通知顺序颠倒了,当最终通知先执行时,连接被关闭, 后置通知commit就不能提交产生的报错。 反正就是到执行语句了就是把连接关闭了,由于没连接又重新获取了连接,但是连接已经没有 执行语句了,就算是提交也不好使了。 解决方法:用新版本的Spring就没有这个问题 案例项目(配数据库): 链接:https://pan.baidu.com/s/1nV

weixin_42858422的博客 184

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

PCB 拼版系统近五日迭代复盘:租户隔离、横直料重构与拼版引擎打磨

最近一周主要干了四件事:给系统搭了套多租户数据隔离、把横直料和花式拼的算法整个推倒重写了一版、PCS 到 SET 的枚举逻辑从固定配置改成了全组合搜索、以及前端 UI 做了一轮精修。这篇文章是这段时间的复盘,重点聊聊几个踩过的坑和做过的技术决策。

chenwei83425的专栏 401

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

147.【2024Java八股-全网最全-10w字】

eg: 学校、院校、经验、年龄、跳槽频率…基本包括16种常见使用场景: 、数据共享分布式、、全局 ID、计数器、限流、位统计、购物车、用户消息时间线 timeline、、抽奖、点赞、签到、打卡、商品标签、商品筛选、用户关注、推荐模型、排行榜.详细讲解16种使用场景: https://blog.youkuaiyun.com/zxl646801924/article/details/123202381用户使用id进行查询文章的时候,首先会查询redis数据库,如果在redis中命中数据,那么redis就向用户返回查询的结果

qq_69683957的博客 1736

(附源码)基于springboot的物流配货管理系统的设计与实现-毕业设计 课程设计 250858

物流配货管理系统主要功能模块包括:库存货物、分类信息、货物入库、货物出库、车辆分类、车辆、订单中心、车辆路线、顶大追踪、订单发货、系统管理员、配货管理员、车辆管理员等模块,采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取Mysql作为后台数据的主要存储单元,采用springboot技术、vue.js语言、ajax等技术进行业务系统的编码及其开发,实现了本系统的全部功能.本次报告,首先分析了研究的背景、作用、意义,为研究工作的合理性打下

Q_3461074420的博客 2561

今天犯了一个特别低级的错误分享给大家——Spring面向切面AOP优先级order顺序混乱

嘈杂的环境下写代码果然容易分神和出错,当然了不能找借口给自己开脱,还是技术欠佳,导致的低级错误 问:哥们儿,请教一下springAOP日志打印。没报错就是xml文件指定时候order的打印顺序和我预想不同,请教下什么原因可能引起乱序 如下图 这里数据正常应该反过来,使用注解的时候没问题。测试xml时候会出现Vlidation序号大于logging反应正确 如果小于则如图,顺序异常 你看到...

瑞新の博客:bennyrhys 1929

springAop注解的Bug

不以人人的意志为转义乃天道 512

Spring-Aop(动态代理controller)-bug

为什么80%的码农都做不了架构师?>>> ...

weixin_34174132的博客 536

Spring 基于注解的AOP配置注意事项:通知类方法的执行顺序

Spring 基于注解的AOP配置注意事项 通知类方法的执行顺序 基于XML: 前置通知(Before) → 后置通知(AfterRunning)/异常通知(AfterThrowing) → 最终通知(After) 基于注解 前置通知(Before) → 最终通知(After) → 后置通知(AfterRunning)/异常通知(AfterThrowing) 所以,基于注解的AOP配置通知类的方法...

banmingi的博客 1233

Spring 注解Aop通知类型及执行顺序

1、通知类型 @Before — 前置通知 @AfterReturning — 后置通知 @Around — 环绕通知(目标对象默认不执行,需要手动执行) @After — 最终通知 @AfterThrowing — ...

weixin_43752167的博客 1576

Spring4笔记----AOP的返回通知和异常通知

返回通知: 无论连接点正常返回还是抛出异常,后置通知都会执行。如果只想在连接点返回的时候记录日志,应使用返回通知代替后置通知。 在返回通知中,只需要在@AfterReturning注解中添加returning属性,就可以访问连接点的返回值。 必须在通知方法的签名中添加一个同名参数,在运行时Spring AOP会通过这个参数传递给返回值。 在方法法正常结束后执行的代码  返回通知是可以

沙漏 7589

Srping AOP基于注解和配置文件方式实现前通知,后通知,环绕通知,异常通知,最终通知

Srping AOP基于注解和配置文件方式实现前通知,后通知,环绕通知,异常通知,最终通知 注解方式: 1、切面类 package cn.sz.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotati

侯春强的博客 995
上一篇: Linux中cowsay命令全图鉴
下一篇: 关于阿里云轻量级服务器封25和465端口无法发送邮件问题的解决方案
Princar
博客等级 码龄11年 4粉丝 19原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值