AOP是spring的最重要模块之一,关于AOP的原理,主要就是基于动态代理,可以查看官网Understanding AOP Proxies,本节内容不去深究AOP原理,仅仅列出在spring框架中编写AOP代码时,常用的切点表达式写法,官网上关于AOP这一节的说明,也可以看下,一定会有收获Aspect Oriented Programming with Spring本文也是基于官方文档形成的。

需要说明的是在spring框架中共用了AspectJ的一些注解,且目前仅支持方法级别的增强,AspectJ支持更多的切点表达式,在本文例子中也不去详述,想要了解的可以去看The AspectJTM Programming Guide

由于本文的重点在于切点表达式的例子,所以本文所采用的增强方式一般以环绕增强为主。

1. spring-aop支持的切点表达式关键字

官网很明确的说明了spring支持哪些切点表达式关键字,如下:

Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut expressions:

  • execution: For matching method execution join points. This is the primary pointcut designator to use when working with Spring AOP.
  • within: Limits matching to join points within certain types (the execution of a method declared within a matching type when using Spring AOP).
  • this: Limits matching to join points (the execution of methods when using Spring AOP) where the bean reference (Spring AOP proxy) is an instance of the given type.
  • target: Limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type.
  • args: Limits matching to join points (the execution of methods when using Spring AOP) where the arguments are instances of the given types.
  • @target: Limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type.
  • @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.
  • @within: Limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP).
  • @annotation: Limits matching to join points where the subject of the join point (the method being executed in Spring AOP) has the given annotation.

至于官方暂时不支持的切点表达式关键字,也列举出来了,还表示将来的版本可能会支持更多的关键字:

Other pointcut types

The full AspectJ pointcut language supports additional pointcut designators that are not supported in Spring: call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, and @withincode. Use of these pointcut designators in pointcut expressions interpreted by Spring AOP results in an IllegalArgumentException being thrown.

The set of pointcut designators supported by Spring AOP may be extended in future releases to support more of the AspectJ pointcut designators.

切点表达式之间支持&&, || ! 连接,连接时候可以采用具体的表达式,也可以采用pointcut注解对应的方法签名:比如在spring中自定义注解中用到的myAnnoCut()&&myPointCut()

2. 常用切点表达式

采用execution关键字定义的切点表达式格式如下:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)throws-pattern?)

表达式中除了返回值类型匹配规则ret-type-pattern (通常是 *来匹配所有返回值类型)之外的其他类型匹配规则都是可选的

name-pattern方法名,可以是具体的方法名,也可以用*圈定所有方法

param-pattern方法入参:()匹配无参方法,(..)匹配多参数方法,(*)匹配单参数任意入参类型的方法,(*,String)匹配有两个入参的方法,第一个可以是任意类型,第二个必须是字符串类型。

以下是官方文档中提到的一些表达式:

execution(public * *(..)) //匹配所有public方法
execution(* set*(..))//匹配所有方法名开头为set的方法
execution(* com.xyz.service.AccountService.*(..))//匹配AccountService下的所有方法
execution(* com.xyz.service.*.*(..))//匹配service包下的所有方法
execution(* com.xyz.service..*.*(..))//匹配service包或其子包下的所有方法
within(com.xyz.service.*)//匹配service包下的所有方法
within(com.xyz.service..*)//匹配service包或其子包下的所有方法
this(com.xyz.service.AccountService)//匹配所有实现了AccountService接口的类的代理类的方法(注意是代理类)
target(com.xyz.service.AccountService)//匹配所有实现了AccountService接口的类的方法(注意是本类)
args(java.io.Serializable)//匹配只有一个入参,且入参实现了Serializable接口的方法
@target(org.springframework.transaction.annotation.Transactional)//匹配类上标注了@Transactional注解的类中方法
@within(org.springframework.transaction.annotation.Transactional)//匹配运行时子类上标注了@Transactional注解的类中方法
@annotation(org.springframework.transaction.annotation.Transactional)//匹配所有打了@Transactional注解的方法
@args(com.xyz.security.Classified)//匹配只有一个入参,且运行时入参有@Classified注解的方法
bean(tradeService)//匹配命名为tradeService的类的方法
bean(*Service)//匹配命名后缀为Service的类的方法

‘this’ is more commonly used in a binding form. See the section on Declaring Advice for how to make the proxy object available in the advice body.

关于上面@target和@within区别请看博客

3. 运算符组合切点表达式

这一部分直接列举几个,基础表达式会写之后,组合按照自己想圈定的范围进行组合运算匹配即可:

//或(||)运算符
@Pointcut("execution(* com.xxx.yyy.service.*.*.*(..))||" +"execution(* com.xxx.yyy.api.*.*.*(..))")
public void myElseCut(){};
//与(&&)运算符
@Pointcut("execution(* com.xxx.yyy.controller..*.*(..))"+ "&& @within(org.springframework.web.bind.annotation.RestController)")
public void myAndCut(){};
//非(!)运算符
@Pointcut("@within(org.springframework.validation.annotation.Validated)"+ "&& !@within(org.springframework.web.bind.annotation.RestController)"+ "&& !@within(org.springframework.stereotype.Controller)")
public void myNotCut(){};

组合切点表达式均可以拆分成两个切点声明,然后再使用运算符连接,这样可读性好些,例如:

@Aspect
@Component
public class MyselfAnnotionAspect {//通过切点表达式定义切点/**@Pointcut("execution(* com.enjoyican.demo.selfannotion.service.impl..*(..))")public void myPointCut(){};@Pointcut("@annotation(MyselfAnnotion)")public void myAnnoCut(){};@Pointcut("within(com.enjoyican.demo.selfannotion.service..*)")public void myWithinCut(){};@Pointcut("target(com.enjoyican.demo.selfannotion.service.MyAnnotionTestService)")public void myTargetCut(){};*/@Pointcut("@target(MyselfAnnotion)")public void myAtTargetCut(){};@Pointcut("bean(myAnnotionTestServiceImpl)")public void myBeanCut(){};//定义方法增强类型(本例子采用环绕增强)@Around("myBeanCut()&&myAtTargetCut()")public Object around(ProceedingJoinPoint point) throws Throwable {System.out.println("AOP切面在执行service方法之前增强");point.proceed();System.out.println("AOP切面在执行service方法之后增强");return null;}
}

总结

对于切点表达式的熟悉可以使我们在项目中更好的写出匹配到更灵活规则的类的表达式,强烈建议看下官网中Aspect Oriented Programming with Spring这一节的内容,很多我们平时用的其实官方文档上都说明了,而且这里的英文相对简单,除了一些专业词汇外都是很通俗易懂的语句。

如有疑问,可在我的个人博客spring-aop常用切点表达式下留言或者在CSDN留言即可

spring-aop常用切点表达式相关推荐

  1. spring aop抽取切点表达式

  2. Spring学习之AOP的切点表达式详解

    1.背景知识 在Sping中使用AOP的主要工作是配置织入关系,使用<aop:config>标签代表这一段是织入关系的配置 首先,用<aop:aspect>标签声明一个切面,这 ...

  3. Spring 中的切点表达式介绍

    Spring 中的切点表达式介绍 翻译原文链接 Introduction to Pointcut Expressions in Spring 1. 概述 在本教程中,我们将讨论 Spring AOP ...

  4. 关于Spring AOP中切点修饰符@annotation、@args与args约束说明

    前言 于其说这是一篇文章,不如说这是一篇笔记,主要介绍了@annotation.@args和args的作用以及一些坑点.这里主要记录一些项目用到的,没有成一套体系,网上其他文章对Spring AOP的 ...

  5. spring aop中pointcut表达式

    spring aop中pointcut表达式 本文主要介绍spring aop中9种切入点表达式的写法 execute within this target args @target @within ...

  6. Spring| AOP之 切点(Pointcut)

    文章目录 一. 什么是切点? 二. 切点表达式的使用? 三. Spring AOP所支持的AspectJ切点指示器 一. 什么是切点? 通知定义了切面的"什么"和"何时& ...

  7. spring aop 中切面表达式规则

    spring AOP 可以通过两中方式配置: ①注解 (很简单) ②xml文件配置 这里通过说的通过xml 配置中的切面表达式 <!-- 配置事务切面 --> <aop:config ...

  8. Spring Aop pointcut expression表达式解析

    为什么80%的码农都做不了架构师?>>>    Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression&quo ...

  9. Spring定时任务常用Cron表达式

    我们在做springboot项目时候,经常会用到定时任务,而用到定时任务就一定会涉及到Cron表达式的书写 一.Cron表达式是什么? Cron:计划任务,是任务在约定的时间执行已经计划好的工作,而C ...

最新文章

  1. 模仿Hibernate的逆向工程_java版_源码下载
  2. 【C++ 语言】Visual Studio 配置 POSIX 线程 ( Windows 不支持 POSIX | 配置文件下载 | 库文件说明 | 配置过程 )
  3. 最全面详细讲解Oracle入门
  4. MySQL之alter和upate
  5. 计算机基础--认识CPU
  6. 【Java数据库】SQL时间类型Date Time Timestamp区别、插入/取出指定时间段的数据
  7. C++ dlopen mini HOWTO 一篇非常好的介绍C++ dlopen linux/mac os x 编程的资料
  8. Docker最全教程之MySQL容器化 (二十五)
  9. MySQL not in查询不出数据(MySQL not in 无效)
  10. xss img onerror java_java后台防止XSS的脚本攻击
  11. KafkaController介绍
  12. 【ElasticSearch】Es 源码之 CacheService 源码解读
  13. P2424 约数和 真丶除法分块
  14. 文章2021_01_05_stata15在mac上的dta编码问题和系统crash
  15. TCPUDP测试工具
  16. excel冻结行和列_说一说有些人在EXCEL中还不会用的冻结窗格
  17. LittleVGL--07lv_obj基础对象介绍、API 接口、例程演示
  18. intel edison固件更新
  19. TI15.4STACK协议栈解读
  20. 路由协议Ⅰ(RIP、OSPF、IS-IS、IGP、BGP等)

热门文章

  1. 用python实现一个自动保存复制图片的功能
  2. 【重磅推出】Oracle技术嘉年华首届实践培训专场免费开放
  3. 小哈机器人发布新品_解决孩子学习烦恼 小哈教育机器人二代新品上市
  4. ​清华大学提出基于生成对抗神经网络的自然图像多风格卡通化方法并开源代码
  5. 剑指offe 替换空格
  6. 非线性优化汇总——Matlab优化工具箱(持续更新中)
  7. 相册服务器维护,相册云服务器
  8. 如何运用Microsoft Office Project 2003来做项目计划
  9. 【opencv】动态背景下运动目标检测 SURF配准差分
  10. idea当中批量替换变量名字