前言

于其说这是一篇文章,不如说这是一篇笔记,主要介绍了@annotation@argsargs的作用以及一些坑点。这里主要记录一些项目用到的,没有成一套体系,网上其他文章对Spring AOP的切点修饰符可能有比较全的描述。如果以后有遇到其他场景,会在这里补充。

背景

主要是实习公司需要开发一个注解来实现某些特定功能,项目是基于Spring Boot搭建的,因此很容易想到Spring的AOP技术来实现。通过查阅资料和官方文档,发现@annotation注解可以满足这个需求。同时我也研究了@args与·args两个修饰符,讨论一下这两个修饰符到底在干什么。

Spring AOP原理

Spring的AOP使用动态代理模式。在代理模式中有两个对象:代理对象与被代理对象(目标对象),代理模式中是说使用代理对象来操作被代理对象,而动态代理,说明这个代理对象可以根据需要生成,这就是“动”的含义。

关键就在于这个代理对象,我们既然可以在代理对象中调用被代理对象的方法,那么我们就可以在方法执行前、后等做一些操作,这种操作叫做类增强。我们定义方法,写各种各样的表达式,目标就是要匹配正确的方法做类增强。

所以,我们就遇到了第一个坑点:为什么AOP的切点定义不起作用?
大方向有两个原因:

  • 切点定义有问题
  • Spring为你生成的根本不是代理对象
    第二点的排查比较容易,找到你期望增强的方法,然后运行debug模式,观察定义目标方法的对象是不是代理对象:

    例如,TestController就不是代理对象,xServiceImpl就是代理对象,而且是通过GCLIB进行动态代理的
    相关阅读:spring 依赖注入时,什么时候会创建代理类

切点修饰符

@annotation

定义

官方定义:

Limits matching to join points where the subject of the join point (the method being run in Spring AOP) has the given annotation.

也就是说,如果把你定义的注解修饰在某一个方法上,那么就会命中,执行定义的类增强逻辑。

例子

定义一个注解@append,用于在字符串前后增加一些符号。例如接收到的字符串为hello,输出*** hello ***

  • Append注解定义
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Append {public String word() default "***";
}
  • 注解处理器定义
/*** Append的注解处理器*/
@Aspect
@Component
public class AppendProcessor {@Around("@annotation(appendAnnotation)")public String process(ProceedingJoinPoint joinPoint, Append appendAnnotation) throws Throwable{String res = appendAnnotation.word() + " " + joinPoint.proceed() + " " + appendAnnotation.word();return res;}
}

@annotation(…)传入的是注解对象的引用,可以是类型引用

  • service方法定义

@Service
public class XServiceImpl {@Appendpublic String foo(String val) {return val;}
}
  • controller定义
@Controller
@RestController
public class TestController {@Autowiredprivate XServiceImpl xService;@GetMapping("/hello")public String hello() {return xService.foo("Hello Word!");}}

运行结果(关注控制台):

args族

对于args约束,我的理解是用于限制匹配方法的参数类型。这个参数有两种,一种是针对普通方法的,另外一种是针对注解的

args

官方定义

Limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types.

这是针对普通方法的,从定义中可以知道,args用来限制匹配方法的参数类型。

使用args,可以传递匹配方法的调用参数

例子

@annotation那一节中的例子一样,我们修改一下注解处理器

  • 注解处理器定义
/*** Append的注解处理器*/
@Aspect
@Component
public class AppendProcessor {@Around("@annotation(appendAnnotation) && args(val)")public String process(ProceedingJoinPoint joinPoint, Append appendAnnotation, String val) throws Throwable{System.out.println(val);String res = appendAnnotation.word() + " " + joinPoint.proceed() + " " + appendAnnotation.word();return res;}
}

运行结果:

同时观察控制台,会发现val的值是调用匹配方法所传递的值,即Hello Word!

如果我把注解处理器中val的类型改成Integer会发生什么呢?

/*** Append的注解处理器*/
@Aspect
@Component
public class AppendProcessor {@Around("@annotation(appendAnnotation) && args(val)")public String process(ProceedingJoinPoint joinPoint, Append appendAnnotation, Integer val) throws Throwable{System.out.println(val);String res = appendAnnotation.word() + " " + joinPoint.proceed() + " " + appendAnnotation.word();return res;}
}

运行结果:

可以发现,方法匹配失败了,因为打了@Append注解方法的第一个参数是String,而不是Integer

@args

官方定义

Limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given types.

@标志的说明跟注解有关,用来描述方法参数的封装类是否有某个注解。这某个注解的作用域要有

例子

@annotation那一节中的例子的基础上,定义一个新的注解@Demo

  • @Demo注解定义
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Demo {}
  • 新定义一个YService,与XService做区分,YService上有@Demo注解
@Service
@Demo
public class YServiceImpl {public void foo() {}
}
  • 修改Xservice中的foo方法:
@Service
public class XServiceImpl {@Appendpublic String foo(YServiceImpl yService, String val) {System.out.println("方法开始执行");return val;}
}
  • 在注解处理器中新增一个方法
    @Around("@annotation(appendAnnotation) && @args(cn.acmsmu.aop.Demo,..)")public String process2(ProceedingJoinPoint joinPoint, Append appendAnnotation) throws Throwable{String res = appendAnnotation.word() + " " + joinPoint.proceed() + " " + appendAnnotation.word();System.out.println(res);return res;}

这里的@args表示匹配方法可以有多个参数,第一个参数的类必须被@Demo注解修饰

运行结果

共同点与区别

  • 共同点:都是对目标方法的参数类型进行限制
  • 区别:
    • args: 单纯针对待增强方法的参数类型,不会关系参数的类
    • @args: 关注待增强方法参数的类是否被某个注解修饰

关于Spring AOP中切点修饰符@annotation、@args与args约束说明相关推荐

  1. Spring AOP中定义切点(PointCut)和通知(Advice)

    本文讨论一下Spring AOP编程中的两个关键问题,定义切点和定义通知,理解这两个问题能应付大部分AOP场景. 如果你还不熟悉AOP,请先看AOP基本原理,本文的例子也沿用了AOP基本原理中的例子. ...

  2. Spring AOP 中的切点是什么?如何定义切点?

    Spring AOP 中的切点是什么?如何定义切点? 什么是切点? 在 Spring AOP 中,切点(Pointcut)是指一组连接点(Join Point)的集合.连接点是程序执行过程中的某个特定 ...

  3. Spring AOP中定义切点PointCut详解

    1.AOP是什么? 软件工程有一个基本原则叫做"关注点分离"(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的问题.这年 ...

  4. java方法设置切点_java相关:Spring AOP中定义切点的实现方法示例

    java相关:Spring AOP中定义切点的实现方法示例 发布于 2020-6-6| 复制链接 摘记: 本文实例讲述了Spring AOP中定义切点的实现方法.分享给大家供大家参考,具体如下:一 配 ...

  5. Spring AOP中pointcut 切点详解

    Spring AOP中pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方 ...

  6. aspect 方法入参 获取_谈谈Spring AOP中@Aspect的高级用法示例

    前言 本文主要跟大家分享介绍了关于Spring AOP中@Aspect的高级用法,下面话不多说了,来随着小编一起看看详细的介绍吧. 1 切点复合运算 支持在切点定义中加入以下运算符进行复合运算: 运算 ...

  7. 正确理解Spring AOP中的Around advice

    Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before ad ...

  8. Spring :Spring AOP 中的一些术语

    1.美图 2.概述 2.1 连接点(Jointpoint) 连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行.方法调用.字段调用或处理异常等等,S ...

  9. Spring Aop中解析spel表达式,实现更灵活的功能

    前言 在Spring Aop中,我们可以拿到拦截方法的参数,如果能结合spel表达式,就能实现更加灵活的功能.典型的实现有Spring的缓存注解: @Cacheable(value = "u ...

最新文章

  1. 在刚刚结束的ACL 2019上,知识图谱领域都发生了哪些大事?
  2. css根据文字长度实现宽度自适应
  3. C语言 socket listen()函数(socket()函数创建的socket(套接字描述符)默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求)
  4. html状态查询爱站,批量获取爱站数据
  5. openjdk jvm_Java / JVM是如何构建的? 采用OpenJDK是您的答案!
  6. jersey客户端_项目学生:带有Jersey的Web服务客户端
  7. 小程序mpvue图片绘制水印_开发笔记:使用 mpvue 开发斗图小程序
  8. js模板引擎 之handlebars.js
  9. 产品要想跑得赢,政策定价来帮您
  10. 自己动手写Docker系列 -- 5.1实现容器的后台运行
  11. 做实体行业现在难吗?
  12. 追赶法求解三对角线性方程组的MATLAB程序
  13. Javascript第六章世上最全常用RegExp正则表达式及表单验证源码第七课
  14. 打不开_网站源码安装后打不开?教你解决打不开
  15. fedora安装java
  16. ce修改器我的世界服务器,ce修改器怎么修改金钱?ce修改器无限金钱图文教程
  17. 基于Java的超级玛丽游戏的设计与实现(含源文件)
  18. Web安全深度剖析第三章读书笔记
  19. Waymo无人车报告:通往自动驾驶之路
  20. K-means(K均值原型聚类)

热门文章

  1. QMessageBox.question报错:TypeError: question(QWidget, str, str, buttons: Union[QMessageBox.StandardBut
  2. Python的__init__.py文件作用
  3. 企业如何防范和处理负面舆情危机
  4. MacType - 美化 Windows 字体的神器!(让字体渲染显示效果比苹果电脑更清晰炫丽)
  5. 畅游云南、迷恋丽江、爱在泸沽湖
  6. Transactional注解原理解析
  7. 【赵强老师】SQL中的子查询
  8. dxperience 10.1.4 下载 汉化 破解
  9. 设置双卡不同的来电默认铃声
  10. 8-异前列腺素检测ELISA试剂盒检测原理实用资料