Spring AOP切入点表达式
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP切入点表达式相关的知识,希望对你有一定的参考价值。
文章目录
AOP切入点表达式
1. 之前写法的问题
我们之前写切入点是这样的:
execution(void com.yyl.dao.BookDao.update())
看着还行,但是这样一个方法一配置会产生一个问题:
问题1:按照上面的形式去编写切入点,一个两个还行,要是该类中的很多方法都要编写AOP是十分麻烦的,那么我们该如何简化切入点表达式中包名和参数类型书写?
还是刚才的update函数,虽然我们编程是按照接口编程,但是最后运行还是实现类,所以下面两个对于接口与实现类的update描述方式都是对的
- 描述方式一:执行com.yyl.dao包下的BookDao接口中的无参数update方法
execution(void com.yyl.dao.BookDao.update())
- 描述方式二:执行com.yyl.dao.impl包下的BookDaoImpl类中的无参数update方法
execution(void com.yyl.dao.impl.BookDaoImpl.update())
问题2:那么这样又会产生一个问题,两种混用的话最后看起来会很乱,到底用那种方式去写呢?
下面就引入了AOP切入点表达式,见名知意,他和其他的xx表达式差不多,都有固定格式、通配符等概念,可以帮我们简化AOP切片编程的书写,也可以帮我们约定书写格式规范:
2. 切入点表达式概念
首先回顾一下什么是切入点?
- 切入点:要进行增强的方法
那么切入点表达式就简单了,他就是一种切入点的描述方式
- 切入点表达式:要进行增强的方法的描述方式
3. 语法格式
3.1 切入点表达式标准格式:
动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数) 异常名)
其中的各部分说明如下:
参数 | 说明 |
---|---|
动作关键字 | 描述切入点的行为动作,例如execution表示执行到指定切入点 |
访问修饰符 | public,private等,可以省略 |
返回值 | 写返回值类型 |
包名 | 多级包使用点连接 |
类/接口名 | |
方法名 | |
参数 | 直接写参数的类型,多个类型用逗号隔开 |
异常名 | 方法定义中抛出指定异常,可以省略 |
例如:
execution(public User com.yyl.service.UserService.QueryById(int))
3.2 通配符
切入点表达式也有通配符的概念
通配符目的:可以使用通配符描述切入点,快速描述。
有下面三个常用的通配符:
*
:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现
例如:匹配com.yyl包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法
execution(public * com.yyl.*.UserService.find*(*))
..
:多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写
例如:匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法
execution(public User com..UserService.findById(..))
+
:专用于匹配子类类型
例如:匹配包下的XXXService的所有方法
execution(* *..*Service+.*(..))
3.3 书写技巧
- 所有代码按照标准规范开发,否则以下技巧全部失效
- 描述切入点通常描述接口,而不描述实现类
- 访问控制修饰符针对接口开发均采用public描述(可省略访问控制修饰符描述)
- 返回值类型对于增删改类使用精准类型加速匹配,对于查询类使用*通配快速描述
- 包名书写尽量不使用…匹配,效率过低,常用
*
做单个包描述匹配,或精准匹配 - 接口名/类名书写名称与模块相关的采用*匹配,例如
UserService
书写成*Service
,绑定业务层接口名 - 方法名书写以动词进行精准匹配,名词采用
*
匹配,例如getById
书写成getBy*
,selectAll
书写成selectAll
- 参数规则较为复杂,根据业务方法灵活调整
- 通常**不使用异常作为匹配**规则
4. 实战演练
还是上面的update函数,你想想还能怎么写
@Pointcut("execution(void com.yyl.dao.BookDao.update())")
@Pointcut("execution(void com.yyl.dao.impl.BookDaoImpl.update())")
@Pointcut("execution(void com.*.*.*.update())")
@Pointcut("execution(* *..*(..))")
@Pointcut("execution(* *..*e(..))")
@Pointcut("execution(void com..*())")
但是要注意,下面这样是不行的update(*)
,这样说明里面有参数
@Pointcut("execution(* com.yyl.dao.impl.BookDaoImpl.update(*))") //no
其他的没问题
以上是关于Spring AOP切入点表达式的主要内容,如果未能解决你的问题,请参考以下文章