Spring AOP 之 多切面

article/2025/8/18 19:36:01

接着上文:https://blog.csdn.net/single_wolf_wolf/article/details/81772837

多切面 相对来说,只是定义多个切面类,同时配置类中设置一下,

demo如下:

首先定义一个接口:

package com.cmb.multi;public interface MultiAsp {public void test();
}

 

再给出实现:

package com.cmb.multi;import org.springframework.stereotype.Component;@Component
public class MultiAspImpl implements MultiAsp {public void test() {System.out.println("This is a test for multi aspect!");}}

不要忘记@Component

其中test()是连接点

切面一:

package com.cmb.multi;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class Aspect1 {@Pointcut("execution(* com.cmb.multi.MultiAspImpl.test(..))")public void print(){}@Before("print()")public void before(){System.out.println("before 1 ....");}@After("print()")public void after(){System.out.println("after 1 ....");}@AfterReturning("print()")public void afterReturning(){System.out.println("afterReturning 1 ....");}@AfterThrowing("print()")public void afterThrowing(){System.out.println("afterThrowing 1 ....");}}

切面二:

package com.cmb.multi;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class Aspect2 {@Pointcut("execution(* com.cmb.multi.MultiAspImpl.test(..))")public void print(){}@Before("print()")public void before(){System.out.println("before 2 ....");}@After("print()")public void after(){System.out.println("after 2 ....");}@AfterReturning("print()")public void afterReturning(){System.out.println("afterReturning 2 ....");}@AfterThrowing("print()")public void afterThrowing(){System.out.println("afterThrowing 2 ....");}
}

切面三:

package com.cmb.multi;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class Aspect3 {@Pointcut("execution(* com.cmb.multi.MultiAspImpl.test(..))")public void print(){}@Before("print()")public void before(){System.out.println("before 3 ....");}@After("print()")public void after(){System.out.println("after 3 ....");}@AfterReturning("print()")public void afterReturning(){System.out.println("afterReturning 3 ....");}@AfterThrowing("print()")public void afterThrowing(){System.out.println("afterThrowing 3 ....");}
}

然后给出配置类:MultiConfig

package com.cmb.multi;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.cmb.multi")
public class MultiConfig {@Beanpublic Aspect1 getAspect1(){return new Aspect1();}@Beanpublic Aspect2 getAspect2(){return new Aspect2();}@Beanpublic Aspect3 getAspect3(){return new Aspect3();}
}

最后我们测试一下:主函数:

package com.cmb.multi;import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class MultiMain {public static void main(String[] args) {//使用AnnotationConfigApplicationContext 加载配置文件ApplicationContext ctx = new AnnotationConfigApplicationContext(MultiConfig.class);MultiAsp multiAsp = ctx.getBean(MultiAsp.class);multiAsp.test();}}

结果如下:

before 1 ....
before 2 ....
before 3 ....
This is a test for multi aspect!
after 3 ....
afterReturning 3 ....
after 2 ....
afterReturning 2 ....
after 1 ....
afterReturning 1 ....

结果很尴尬,和书本上不一致,书上说目前这种写法的话,多个切面是无序的,结果应该是

before 1 ....
before 3 ....
before 2 ....
This is a test for multi aspect!
after 2 ....
afterReturning 2 ....
after 3 ....
afterReturning 3 ....
after 1 ....
afterReturning 1 ....

但是,笔者不信邪,连续运行了十几次,结果还是第一种,目前猜测是我的框架比较新,不知道是不是框架内部默认了顺序,探后我修改MultiConfig配置类如下:

@Beanpublic Aspect3 getAspect3(){return new Aspect3();}@Beanpublic Aspect1 getAspect1(){return new Aspect1();}@Beanpublic Aspect2 getAspect2(){return new Aspect2();}

对,就是把Aspect3放到了最上面的位置,然后查看结果如下:

before 3 ....
before 1 ....
before 2 ....
This is a test for multi aspect!
after 2 ....
afterReturning 2 ....
after 1 ....
afterReturning 1 ....
after 3 ....
afterReturning 3 ....

结果居然变换了,目前看来,Spring AOP框架中关于多个切面的执行顺序是按照配置类中Bean的注入来的

然后我们使用@Order 把切面分别修改为:

@Aspect
@Order(3)@Aspect
@Order(1)@Aspect
@Order(2)

同时配置类中Bean顺序还是3, 1 ,2

运行主函数,结果如下:

before 1 ....
before 2 ....
before 3 ....
This is a test for multi aspect!
after 3 ....
afterReturning 3 ....
after 2 ....
afterReturning 2 ....
after 1 ....
afterReturning 1 ....

看到没!!! 运行顺序被掰过来, 对吧,这个就是@Order的功劳,这里就是使用这个注解规定多切面的执行顺序,最后给出一张图,SPringAOP的多代理情况下,,使用的是责任链模式:

参考文献:《javaEE互联网轻量级框架整合开发》

 

 

 


http://chatgpt.dhexx.cn/article/2A6ShSQH.shtml

相关文章

spring切面注解失效

在项目中使用切面注解做数据脱敏时,导出的数据也需要脱敏处理,遇到了在一个类里面调用本类的方法切面失效,解决方法如下: 切面注解: package com.t3.ts.driver.resume.aspect;import java.lang.annotation.*;/*** Description: 数据脱敏注解 Filed* Date: 2019/9/10* Author:…

自定义切面类

直接贴入代码 ,注释写的很清楚 此处为controller层 方法上加上自定义的切面注解 入参实体 public class TestM extends BaseModel{/****/private static final long serialVersionUID 1L; private String a;public String getA() {return a; }public void setA(S…

java 切面 注解_十、使用注解定义切面

一、本课目标 掌握使用注解实现AOP的方法 二、使用注解定义切面 2.1简介 AspectJ 面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入。 @AspectJ AspectJ5新增的功能,使用JDK5.0注解技术和正规的AspectJ切点表达式语言描述切面(所以在使用@Aspect…

Spring 创建切面

目录 1、概述 2、切点类型 3、切面类型 4、静态普通方法名匹配切面 5、静态正则表达式方法匹配切面 6、动态切面 7、流程切面 8、复合切点切面 9、总结 1、概述 在前面介绍各类增强时,大家可能没有注意到一个问题:增强被织入到目标类的所有方法…

Spring基础:切面

前言在之前的文章中总结了 AOP 在 Spring 中的作用及地位,在分析 AOP 时涉及到切面的内容,这一节详细的分析切面的知识点。 正题 在开始文章前,有几个问题需要思考一下: 切面到底是神马切面的构成切面有哪些实现类切面有哪些类型…

java使用spring aop切面编程

aop概念 1、切面(Aspect) 首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类定义完成之后(封装)。每次实例化一个对象,对类定义中的成员变量赋值,就相当于对这个立方体…

【Spring】面向切面编程详解(AOP)

文章目录 一、AOP概述什么是AOPAOP应用场景 二、AOP的基本术语术语介绍术语举例详解 三、AOP实例说明四、通知类型详解概述前置通知后置通知环绕通知最终通知 六、AOP实现声明式事务结语 🌕博客x主页:己不由心王道长🌕! 🌎文章说明…

时间序列预测方法

之前一直在看时间序列预测方法的文献,最近终于有点头绪了,然后就花了些时间来做一下整理。时间序列预测方法可分为传统的,基于机器学习的和基于深度学习的,以下每一方面都列举了几个比较经典的模型算法。 目录 1 背景 2 传统的时…

时间序列预处理

数据预处理的主要流程为:数据清洗、特征选择、归一化处理、划分窗口、Shuffle和划分数据集等五个阶段。选用何种方法没有统一的标准,只能根据不同类型的分析数据和业务需求,在对数据特性做了充分的理解之后,再选择与其最适配的数据…

时间序列分析相关概念

1. 在时间序列分析中, 数学模型是什么?数学公式又是什么?数学推导过程又是什么?… … 一句话:用数学公式后者符号来表示现实存在的意义。数学是“万金油”的科学,它是作为工作和分析方法运用到某个学科当中…

时间序列预测方法总结

前言 对时间序列数据预测模型做个简单的分类,方便日后对其进一步研究,理清楚技术更新发展方向。 时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征。 预测场景 单步预测 单步单变量预测 :在时间序…

时间序列的聚类方法

时间序列的聚类方法 时间序列是按照时间排序的一组随机变量,它通常是在相等间隔的时间段内,依照给定的采样率,对某种潜在过程进行观测的结果。 时间序列数据是实值型的序列数据,具有数据量大、数据维度高以及数据是不断更新的等…

【时间序列预测】Autoformer 长时间序列预测

论文链接:http://xxx.itp.ac.cn/pdf/2106.13008.pdf Abstract 延长预测时间是极端天气预警和长期能源消耗规划等实际应用的关键需求。本文研究时间序列的长期预测问题。先前的基于 Transformer 的模型采用各种 self-attention 机制来发现长期依赖关系。然而&…

时间序列分析预测

全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 时间序列中常用预测技术,一个时间序列是一组对于某一变量连续时间点或连续时段上的观测值。参考:https://blog.csdn.net/u010414589/article/details/49622625…

时间序列预测

问题简介 简单来说,时间序列是按照时间顺序,按照一定的时间间隔取得的一系列观测值,比如我们上边提到的国内生产总值,消费者物价指数,利率,汇率,股票价格等等。时间间隔可以是日,周…

时间序列分析

http://blog.csdn.net/pipisorry/article/details/62053938 时间序列简介 时间序列是时间间隔不变的情况下收集的时间点集合。这些集合被分析用来了解长期发展趋势,为了预测未来或者表现分析的其他形式。但是什么时间序列?与常见的回归问题的不同&…

时间序列模型调查

RNN 模型 Recurrent Neural Network (回流神经网络,有的译做递归神经网络) 时间序列模型最常用最强大的的工具就是递归神经网络(recurrent neural network, RNN)。相比与普通神经网络的各计算结果之间相互独立的特点,RNN的每一次隐含层的计算结果都与当前输入以及上一次的…

时间序列模型

1. 时间序列分析方法概述 一个时间序列往往是一下几类变化形式的叠加或耦合。 (1)长期趋势变动:反映主要变化趋势; (2)季节变动 (3)循环变动 (4)不规则变动 使…

python创建时间序列_python 时间序列

将dataframe的列转化为时间序列 #https://www.cnblogs.com/bolgbjg/p/14013300.html #datetime.now()获取现在的时间,now.year,获取现在的年份,其他以此类推 #timedelta()表示两个datetime之间的时间差,默认单位是天 strftime()参数, strftim…

时间序列(数据分析)

目录 第11章 时间序列 11.1 日期和时间数据的类型及工具 11.1.1 字符串与datetime互相转换 11.2 时间序列基础 11.2.1 索引、选择、子集 11.2.2 含有重复索引的时间序列 11.3 日期范围、频率和移位 11.3.1 生成日期范围 11.3.2 频率和日期偏置 11.3.3 移位&#xff0…