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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android Studio入门教程(新手必看)[通俗易懂]

    Android Studio入门教程(新手必看)[通俗易懂]上篇文章已经说过了AndroidStudio的安装配置,从这里开始我们就来完成第一个Android项目吧!如何安装配置还不太熟悉的可以参考这篇文章:AndroidStudio安装配置详细步骤(超详细) 让我们开始第一个Android项目吧1.建立项目选一个EmptyActivity,然后Next默认即可,点击FinishName:文件名Savelocation:文件的保存位置Language:默认Java,会用Kotlin的也可以更改APIlevel:默认即可,级别低运行

    2022年5月1日
    148
  • 如何完成一张机房3d效果图

    如何完成一张机房3d效果图制作机房3D效果图作者:西安曼笛文化传播有限公司     赵希希 随着信息技术的不断发展,网络的更新,平安城市的规划,大量数据中心的建设,机房监控软件也慢慢的推进,机房效果图也有很大的改进。 从cad到简易的效果图在到成熟的3d效果图.如下图1;图2;图3所示:图1图2图3现在的机房效果图不光体现整体的图形,材质,还有会体现很多细节:

    2022年6月2日
    37
  • idea在mac版怎么配置svn_IntelliJ Idea 集成svn 和使用

    idea在mac版怎么配置svn_IntelliJ Idea 集成svn 和使用最近公司的很多同事开始使用IntelliJIdea,便尝试了一下,虽然快捷键与eclipse有些不同,但是强大的搜索功能与“漂亮的界面”(个人认为没有eclipse好看),还是值得我们去使用的。刚开始使用的idea要去集成svn,下载公司的项目。我是用的是TortoiseSVN(小乌龟),下载后安装,然后记住安装路径,我安装的是64位的。TortoiseSVN的下载地址:htt…

    2022年10月17日
    3
  • 获取的string转JSONArray或JSONObject

    获取的string转JSONArray或JSONObject² 返回值:JSON格式字符串{“serviceId”:”3c.park.queryparkstandard”,”resultCode”:0,”message”:”成功”,”dataItems”:[{“objectId”:””,”operateType”:”READ”,”attributes”:{“parkCode”:”park01″,

    2022年6月20日
    33
  • VARIANT、COleVariant 和_variant_t

    VARIANT、COleVariant 和_variant_t 在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。下面让我们来看看OAIDL.H文件中VARIANT定义的一个简化版:structtagVARIANT{ VARTYPEvt; union{  shortiVal;//VT_I2.  longlVal;//VT

    2022年7月18日
    15
  • 区块链钱包_区块链钱包的作用

    区块链钱包_区块链钱包的作用什么是区块链钱包 在介绍区块链钱包之前,我们先详细介绍下比特币的地址生成过程。大的流程是:私钥–》公钥–》地址。先啰嗦一点计算机知识:位,字节,字,KB,MB 位:“位(bit)”是电子计算机中最小的数据单位。每一位的状态只能是0或1。 字节:8个二进制位构成1个“字节(Byte)”,它是存储空间的基本计量单位。1个字节用16进制来表示是两个字符,比如1011…

    2022年10月21日
    2

发表回复

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

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