Spring AOP理解与研发使用

Spring AOP理解与研发使用SpringAOP理解与研发使用:基本理论(基本术语总结+具体开发注意事项+切点正则和指示器规则)+AOP开发应用与分析

大家好,又见面了,我是你们的朋友全栈君。

一、前言

Spring AOP是一种基于方法的AOP,只能用在方法上,在业务上我们一般使用Spring AOP去约定编程一套业务逻辑织入到相关的业务处理中,并抽取通用逻辑默认加入到相关业务中(前置处理后置业务处理或异常处理等),同时在应用上在想对一些现成业务进行干预处理时都会使用(比方说可以考虑对特定方法进行mock操作等处理)。Spring AOP和我们平时开发中使用的约定编程基本类似,本质都是通过约定对相应的方法通过动态代理技术织入约定流程中。本次一些基本的理念还是直接通过自己看过的一些书籍和博客进行总结了,实际应用上基本是结合自己的开发经验进行了一些基本的应用分享,如果有理解错误的地方请留言指正,谢谢!

二、Spring AOP基本理论知识

(一)基本术语总结

术语 基本概念
连接点(join point) 具体被拦截的对象,往往指的就是特定的方法,也可以指某个包路径下的所有类下的所有方法(进行mock干预经常这样干)或直接就是某个类下面的所有方法
切点(point cut) 切面作用的方法不只是单一的,可以通过正则和指示器的规则去定义,适配连接点
通知(advice)

按照约定的流程方法,根据约定织入流程中。

分类:前置通知、后置通知、环绕通知、事后反悔通知、异常通知

目标对象(target) 即被代理对象,也就是上面连接点(join point)中的指定的类
引入(introduction) 增加现有Bean的功能,引入新的类和方法
织入(weaving) 通过动态代理,为原对象生成代理对象,然后与切点定义匹配的连接点拦截,按约定将各类通知织入约定流程中
切面(aspect) Spring AOP通过切面信息来增加Bean的功能或将对应方法织入流程,在切面中定义切点、各类 通知和引入内容

(二)具体开发注意事项

有相关疑问的可以留言直接问,以下内容,只是我平时觉得重点的应用注意事项总结:

  1. ProceedingJoinPoint,继承自连接点JoinPoint,实际作用上就是我们指定的具体某个类或某些类,本质上连接点就是什么类的什么方法
  2. 具体切面采用@Aspect注解标注,切面中定义我们想要约定实现的基本内容,以及相关的通知@Before、@After、@AfterReturning、@AfterThrowing、@Around,各通知中需要统一指明切点,一般我们都是直接定义切点@Pointcut,然后直接在各通知中进行引入即可。
  3. @Around是我们业务干预中的重点流程改造,一般主要干预处理的内容都在该通知中实现,处理上务必重点分析处理逻辑,代码上做兜底是必须操作。
  4. @DeclareParents业务处理中针对老逻辑进行干预并增加功能时,可以考虑采用引入方式处理,即通过该注解指明两个主要参数value和defaultImpl,value指明要增强的目标对象,defaultImpl指引入增强功能的类,具体我们后续案例介绍下。
  5. 非环绕通知中对于参数的处理直接使用JoinPoint(当然也可以不用),例如前置打印参数等内容,环绕通知则使用ProceedingJoinPoint,在使用上需要注意。
  6. 如果多个切面作用的类和方法是一样的,则切面的执行顺序是无序的,如果切面之间需要有先后顺序的的话,需要使用@Order注解或实现Ordered接口实现,数字越小优先级越高,实际处理上如果既有前置通知又有后置通知,则可以看到前置从小到大执行,后置从大到小执行,这说明其内部是一个典型的责任链模式(其应用具体见:)。

(三)切点正则和指示器规则

平时开发时对于切点的定义较多,如果已经很明确处理的切点的话则不需要进行复杂正则配置,但是如果是多类多方法时则正则是必须的。一般我们常用的AspectJ的指示器主要如下表:

AspectJ指示器 描述
arg() 限制连接点匹配参数为制定类型的方法
@args() 限制而连接点匹配参数为指定注解标注的只是方法
execution 用于匹配连接点的执行方法
this() 限制连接点匹配AOP代理的Bean,引用为指定类型的类
target 限制连接点匹配被代理对象为指定的类型
@target 限制连接点匹配特定的执行对象,这些对象要符合指定的注解类型
@within() 限制连接点匹配指定的类型
within() 限制连接点匹配指定的包
@annotation 限定匹配带有指定注解的连接点

基本使用举例如下

联合使用切点指示器

/*匹配任意public访问修饰符修饰的方法*/
@Pointcut("execution(public * (..))")
private void anyPublicOperation() {} 

/*匹配包名以com.zyf.javabasic.trading开头的任意类的所有方法*/
@Pointcut("within(com.zyf.javabasic.trading..)") 
private void inTrading() {} 

/*匹配以com.zyf.javabasic.trading开头的任意类中任意以public访问修饰符修饰的方法*/
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} 

共享切点定义

/*匹配定义在web层且目标对象在com.zyf.javabasic.web包及其子包中的所有类的任意方法*/
@Pointcut("within(com.zyf.javabasic.web..)")
public void inWebLayer() {}

/*匹配定义在service层且目标对象在com.zyf.javabasic.service包及其子包中所有类中的任意方法*/
@Pointcut("within(com.zyf.javabasic.service..)")
public void inServiceLayer() {}

/*匹配定义在数据访问层且目标对象在com.zyf.javabasic.dao包及其子包中所有类中的任意方法*/
@Pointcut("within(com.zyf.javabasic.dao..)")
public void inDataAccessLayer() {}

/*匹配数据库访问层中目标对象在com.zyf.javabasic.dao..(..)及其子包中的任意方法*/
@Pointcut("execution( com.zyf.javabasic.dao..(..))")
public void dataAccessOperation() {}

切点表达式解读与使用示例

/*匹配任意公共方法*/
execution(public * *(..)) 

/*匹配任意方法名以set字符开头的方法*/ 
execution(* set*(..)) 
    
/*匹配com.xyz.service.AccountService类下任意方法*/
execution(* com.xyz.service.AccountService.*(..)) 
    
/*匹配com.zyf.service包及其子包下任意类的所有方法*/     
execution(* com.zyf.service.*.*(..))

/*匹配com.zyf.service包下任意接口的所有方法*/
within(com.zyf.service.*) 

/*匹配com.zyf.service包及其子包下任意类的所有方法*/
within(com.zyf.service..*) 

/*匹配实现AccountService接口的代理的任意方法*/
this(com.zyf.service.AccountService) 

/*匹配实现AccountService接口的目标对象的任意方法*/ 
target(com.zyf.service.AccountService)

/*匹配只带一个参数的方法,且该参数为可序列化参数*/
args(java.io.Serializable) 
 
/*匹配具有Transactional的目标对象任意方法*/
@target(org.springframework.transaction.annotation.Transactional)

/*匹配目标对象声名有Transactional的方法*/  
 @within(org.springframework.transaction.annotation.Transactional)

/*匹配带有个参数的方法,且运行时参数类型绑定有Classified注解*/
@args(com.zyf.security.Classified)
 
/*匹配Spring容器中id或name属性值为tradeService的bean实例的方法*/
bean(tradeService)
 
/*匹配Spring容器中id或name属性值以Service结尾的bean实例的方法*/
bean(*Service)

三、AOP开发应用与分析

(一)方法自动打印出入参举例

(二)mock赋能干预举例

(三)场景业务处理举例

(四)异步业务处理举例

(五)@DeclareParents使用举例

参考文献、书籍和链接

1.杨开振,深入浅出Spring Boot 2.X,中国工信出版社集团/人民邮电出版社,2015.10.

2.Spring AOP详解及其用法(一)_heshengfu1211的博客-CSDN博客_auditable注解

3.Spring AOP 面向切面编程_劳资是学渣丶的博客-CSDN博客

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158125.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月12日 上午6:16
下一篇 2022年7月12日 上午6:16


相关推荐

  • OpenCV中的width与widthStep

    OpenCV中的width与widthStep1.在opencv中width表示的是图像的每行像素数,widthstep表示的是存储一行像素需要的字节数,位了快速读取数据,在opencv中一般使widthStep为4的倍数,从而实现字节的对齐,有利于提高运算速度。2.函数的原型为image->widthStep=(((image->width*image->nChannels*(image->depth&~IPL_DEPTH_SIGN)+7)/8)+align-1)&(~(alig

    2022年5月30日
    48
  • 关于GHO文件怎么安装,GHO文件怎么打开等问题解答

    关于GHO文件怎么安装,GHO文件怎么打开等问题解答首先说下GHO文件是什么,GHO文件是用GHOST软件对电脑硬盘中的系统备份生成的文件.我们用一键备份工具备份电脑系统会生成一个GHO文件,另外我们下载的ghost系统中(如雨林深度之类)也有一个GHO文件.1,问:gho文件怎么装系统,怎么安装gho文件. 答:总的来说是通过ghost软件来安装.比如U盘启动工具,网上的什么老毛桃,大白菜,电脑店之类的U盘启动工具都可以来安装,通过

    2022年7月12日
    17
  • python安装pygame教程_pygame 安装教程

    python安装pygame教程_pygame 安装教程步骤 1 去官网下载 PyGame 注意 要下载对应版本的包其中 如果 python 为以下版本 cp36 就是 python3 6 的意思 2 exe 文件直接安装 whl 文件启动 doc 命令安装 在文件所在位置打开 doc 界面 win10 直接在当前文件夹空白处按住 shift 右键打开 powershell 窗口 输入以下指令安装 pipinstallpy 1 9 3 cp36 cp36m

    2026年3月19日
    2
  • 软件架构设计-软件架构风格、分层架构

    软件架构设计-软件架构风格、分层架构一 软件架构设计软件或计算机系统的软件架构是该系统的一个 或多个 结构 而结构由软件元素 元素的外部可见属性及它们之间的关系组成 软件系统架构是关于软件系统的结构 行为和属性的高级抽象 指定了软件系统的组织结构和拓扑结构 软件架构是可传递可复用的模型 架构就是体系结构 架构设计介于需求分析和软件设计之间 架构设计就是需求分配 即满足 需求的职责分配到组件上 二 架构的模型 4 1 视图逻辑视图 主要支持系统的功能需求 即系统提供给最终用户的服务 用户关注 开发视图 也称为模块 实现 视图

    2026年3月17日
    2
  • 扣子工作流拆解:沉浸式历史故事一键出片!30条作品狂揽50w粉(附教程和源码)

    扣子工作流拆解:沉浸式历史故事一键出片!30条作品狂揽50w粉(附教程和源码)

    2026年3月13日
    3
  • ipv6修改DNS服务-首选DNS服务器:240c::6666「建议收藏」

    ipv6修改DNS服务-首选DNS服务器:240c::6666「建议收藏」下一代互联网国家工程中心推出的IPv6DNS服务首选DNS服务器:240c::6666备用DNS服务器:240c::6644来自下一代互联网国家工程中心官网消息显示,日前,下一代互联网国家工程中心正式宣布推出IPv6公共DNS:240c::6666。通过免费提供性能优异的公共DNS服务,为广大IPv6互联网用户打造安全、稳定、高速、智能的上网体验,助力我国…

    2022年6月2日
    142

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号