Aspect @Pointcut切入点解释
Aspectj切入点语法定义
在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut”切入点”
例如定义切入点表达式 execution (* com.sample.service.impl..*. *(..))
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型, *号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数
AspectJ的Execution表达式
execution()
execution()是最常用的切点函数,其语法如下所示:
execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) 除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。与其直接讲解该方法的使用规则,还不如通过一个个具体的例子进行理解。下面,我们给出各种使用execution()函数实例。
1)通过方法签名定义切点
execution(public * *(..))l
匹配所有目标类的public方法,但不匹配SmartSeller和protected void showGoods()方法。第一个代表返回类型,第二个代表方法名,而..代表任意入参的方法;
execution(* *To(..))l
匹配目标类所有以To为后缀的方法。它匹配NaiveWaiter和NaughtyWaiter的greetTo()和serveTo()方法。第一个*代表返回类型,而*To代表任意以To为后缀的方法;
2)通过类定义切点
execution(* com.baobaotao.Waiter.*(..))l
匹配Waiter接口的所有方法,它匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()方法。第一个代表返回任意类型,com.baobaotao.Waiter.代表Waiter接口中的所有方法;
execution(* com.baobaotao.Waiter+.*(..))l
匹 配Waiter接口及其所有实现类的方法,它不但匹配NaiveWaiter和NaughtyWaiter类的greetTo()和serveTo()这 两个Waiter接口定义的方法,同时还匹配NaiveWaiter#smile()和NaughtyWaiter#joke()这两个不在Waiter 接口中定义的方法。
3)通过类包定义切点
在类名模式串中,“.”表示包下的所有类,而“..”表示包、子孙包下的所有类。
execution(* com.baobaotao.*(..))l
匹配com.baobaotao包下所有类的所有方法;
execution(* com.baobaotao..*(..))l
匹 配com.baobaotao包、子孙包下所有类的所有方法,如com.baobaotao.dao,com.baobaotao.servier以及 com.baobaotao.dao.user包下的所有类的所有方法都匹配。“..”出现在类名中时,后面必须跟“*”,表示包、子孙包下的所有类;
execution(* com...*Dao.find(..))l
匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀。如com.baobaotao.UserDao#findByUserId()、com.baobaotao.dao.ForumDao#findById()的方法都匹配切点。
4)通过方法入参定义切点
切点表达式中方法入参部分比较复杂,可以使用“”和“ ..”通配符,其中“”表示任意类型的参数,而“..”表示任意类型参数且参数个数不限。
execution(* joke(String,int)))l
匹 配joke(String,int)方法,且joke()方法的第一个入参是String,第二个入参是int。它匹配 NaughtyWaiter#joke(String,int)方法。如果方法中的入参类型是java.lang包下的类,可以直接使用类名,否则必须使用全限定类名,如joke(java.util.List,int);
execution(* joke(String,*)))l
匹 配目标类中的joke()方法,该方法第一个入参为String,第二个入参可以是任意类型,如joke(String s1,String s2)和joke(String s1,double d2)都匹配,但joke(String s1,double d2,String s3)则不匹配;
execution(* joke(String,..)))l
匹配目标类中的joke()方法,该方法第 一个入参为String,后面可以有任意个入参且入参类型不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,String s3)都匹配。
execution(* joke(Object+)))l
匹 配目标类中的joke()方法,方法拥有一个入参,且入参是Object类型或该类的子类。它匹配joke(String s1)和joke(Client c)。如果我们定义的切点是execution(* joke(Object)),则只匹配joke(Object object)而不匹配joke(String cc)或joke(Client c)。
args()和@args()
args()函数的入参是类名,@args()函数的入参必须是注解类的类名。虽然args()允许在类名后使用+通配符后缀,但该通配符在此处没有意义:添加和不添加效果都一样。
1)args()
该函数接受一个类名,表示目标类方法入参对象按类型匹配于指定类时,切点匹配,如下面的例子:
args(com.baobaotao.Waiter)
表 示运行时入参是Waiter类型的方法,它和execution(* (com.baobaotao.Waiter))区别在于后者是针对类方法的签名而言的,而前者则针对运行时的入参类型而言。如 args(com.baobaotao.Waiter)既匹配于addWaiter(Waiter waiter),也匹配于addNaiveWaiter(NaiveWaiter naiveWaiter),而execution( (com.baobaotao.Waiter))只匹配addWaiter(Waiter waiter)方法;实际上,args(com.baobaotao.Waiter)等价于execution( *(com.baobaotao.Waiter+)),当然也等价于args(com.baobaotao.Waiter+)。
2)@args()
该函数接受一个注解类的类名,当方法的运行时入参对象标注发指定的注解时,方法匹配切点。这个切点函数的匹配规则不太容易理解,我们通过以下示意图对此进行详细讲解:
图 4 @arg(M)匹配示意图(1)T0、T1、T2、T3具有如图所示的继承关系,假设目标类方法的签名为fun(T1 t),它的入参为T1,而切面的切点定义为@args(M),T2类标注了@M。当fun(T1 t)传入对象是T2或T3时,则方法匹配@args(M)所声明定义的切点;
- 1
- 2
- 3
再看下面的情况,假设方法签名是fun(T1 t),入参对于T1,而标注@M的类是T0,当funt(T1 t)传入T1、T2、T3的实例时,均不匹配切点@args(M)。
图 5 @arg(M)匹配示意图(2)在类的继承树中,①点为方法签名中入参类型在类继承树中的位置,我们称之为入参类型点,而②为标注了@M注解的类在类继承树中位置,我们称之为注解点。判断方法在运行时是否匹配@agrs(M)切点,可以根据①点和②点在类继承树中的相对位置来判别:
- 1
- 2
- 3
1) 如果在类继承树中注解点②高于入参类型点①,则该目标方法不可能匹配切点@args(M),如图 5所示;
2) 如果在类继承树中注解点②低于入参类型点①,则注解点所在类及其子孙类作为方法入参时,该方法匹配@args(M)切点,如图 4所示。
下 面举一个具体的例子,假设我们定义这样的切点:@args(com.baobaotao.Monitorable) ,如果NaiveWaiter标注了@Monitorable,则对于WaiterManager#addWaiter(Waiter w)方法来说,如果入参是NaiveWaiter或其子类对象,该方法匹配切点,如果入参是NaughtyWaiter对象,不匹配切点。如果 Waiter标注了@Monitorable,但NaiveWaiter未标注@Monitorable,则 WaiterManager#addNaiveWaiter(NaiveWaiter w)却不匹配切点,这是因为注解点(在Waiter)高于入参类型点(NaiveWaiter)。
大家应该明白一个道理,所有广为人用的框架/技术等.基本都是两个目的:
1.软件开发期(写代码,测试,上线)内,让开发人员用更少的代码完成同样的功能实现.
2.软件上线后的维护升级器,让让开发人员用更少的代码完成同样的功能实现.
记住这两条,然后我们来看看AOP到底是什么,以及在什么地方能够让我们少写代码?
1.AOP是什么?
面向切面编程,能够让我们在不影响原有功能的前提下,为软件横向扩展 功能 .
2.在什么地方能够让我们少写代码?
要回答问题2,首先解决"横向"扩展什么意思?
理解了这个词基本就能理解AOP了.
软件开发可分为"持久层" "业务层" 控制器层"
所谓的"横向"就是指上面说到的三个层里的任意一层!
使用AOP技术后,用一个方法,就能同时作用与一个层面内所有方法!
上句话不容易理解,栗子来了!
写日志是一个很好的编程习惯,不用AOP技术的话,我们应该怎么写日志?
System.out.println("方法a开始执行");
public void a(){
System.out.println("我是一个方法");
}
System.out.println("方法a执行成功");
上述是一个很简单的日志.两行代码也不多.
可是在真实开发中,面对100个甚至1000个方法时,这样写你会不会被累死?
如果用AOP的话,我们用一个方法就可以搞定所有的日志!
@Around("bean(*Service)")//指定要监控的bean中的方法
public Object testObject(ProceedingJoinPoint jp) throws Throwable{ //参数的意思是代理执行原软件中的方法
System.out.println(jp.getSignature()+"开始执行"); //在方法执行之前执行
Object val = jp.proceed();
System.out.println(jp.getSignature()+"执行成功");//在方法执行之后执行
return val;
}
OK!,搞定.现在所有业务层的方法执行前后都会打出日志了!.
一个方法搞定了需要机械重复的复制粘贴几百行的工作!世界美好了.
本文目的是简单说明使用AOP如何能帮助我们少写代码,具体如何使用请看下一篇.
http://blog.csdn.net/qq_35360135/article/details/79080502
面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。
但是人们也发现,在分散代码的同时,也增加了代码的重复性。什么意思呢?比如说,我们在两个类中,可能都需要在每个方法中做日志。按面向对象的设计方法,我们就必须在两个类的方法中都加入日志的内容。也许他们是完全相同的,但就是因为面向对象的设计让类与类之间无法联系,而不能将这些重复的代码统一起来。
也许有人会说,那好办啊,我们可以将这段代码写在一个独立的类独立的方法里,然后再在这两个类中调用。但是,这样一来,这两个类跟我们上面提到的独立的类就有耦合了,它的改变会影响这两个类。那么,有没有什么办法,能让我们在需要的时候,随意地加入代码呢?这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。
这样看来,AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。有了AOP,OOP变得立体了。如果加上时间维度,AOP使OOP由原来的二维变为三维了,由平面变成立体了。从技术上来说,AOP基本上是通过代理机制实现的。
AOP在编程历史上可以说是里程碑式的,对OOP编程是一种十分有益的补充。
Aspect @Pointcut切入点解释相关推荐
- Spring Aop源码学习--PointCut切入点
PointCut切入点简单来说就是用来指明Advice(增强)所作用的地方(一般指方法),PointCut简单来说是一个基于表达式的拦截条件. PointCut接口及实现类: PointCut接口提供 ...
- 快速上手@Aspect+@Pointcut
1. 解析 @Aspect: AspectJProxyFactory这个类可以通过解析 @Aspect 标注的类来生成代理aop代理对象--手动Aop的方式之一.实现代理的步骤如下: @Aspect ...
- Spring AOP中@Pointcut切入点表达式详解
目录 一.瞅一眼标准的AspectJ Aop的pointcut的表达式 二.SpringAop的十一种AOP表达式 三.演示使用 1.execution: 2.within: 3.this: 4.ta ...
- Spring Aspect @PointCut(execution表达式)
execution(* com.sample.service.impl..*.*(..)) 解释如下: 符号 含义 execution() 表达式的主体: 第一个"*"符号 表示返 ...
- Spring AOP详解一文搞懂@Aspect、@Pointcut、@Before、@Around、@After、@AfterReturning、@AfterThrowing
文章目录 1.AOP是什么 2.AOP中注解的含义 3.Pointcut切入点的语法 4.AOP代码实现 1.AOP是什么 AOP:Aspect Oriented Programming,翻译过来就是 ...
- 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行 ( 定义连接点注解 | 定义 Aspect 切面 | 定义切入点 | 逐个处理切入点的各个连接点 )
文章目录 一.定义 Join Point 连接点注解 二.定义 Aspect 切面 1.定义 Aspect 切面 2.定义 Aspect 切面 3.逐个处理切入点的各个连接点 4.完整 Aspect ...
- Spring AOP中切入点@Pointcut的使用
切入点@Pointcut的使用 在确定切面aspect之后,需要在切面上确定切入点pointcut 定义 注解@pointcut("{切入点}") 其中{切入点}格式如下: exe ...
- (转)使用CGLIB实现AOP功能与AOP概念解释
http://blog.csdn.net/yerenyuan_pku/article/details/52864395 使用CGLIB实现AOP功能 在Java里面,我们要产生某个对象的代理对象,这个 ...
- SpringCloud使用@Aspect面向切面处理Web请求日志
@Aspect面向切面处理Web请求日志 文字解释 代码实现 实现方式一: 实现方式二: 文字解释 AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译 ...
最新文章
- 多分辨率图像的快速查询
- 阿里巴巴天池大数据竞赛黄金联赛全面开战,全球同步报名,只为寻找最聪明的你!...
- 支持中文的算法可视化网站,你想要的算法这都有
- linux 文件重命名或文件移动
- Tensor看这一篇就够了!
- ExactScan pro for mac(扫描仪整合工具)
- 【vuejs面试题】务必熟知的vuejs面试题「务必收藏」
- FISCO BCOS java sdk 组装交易的代码位置
- Socket.io 的 emit
- matlab画森林图,R语言meta分析(4)网状Meta 分析
- 人力资源专员岗位职责和要求
- 【数据结构】串(一)—— 串的基础知识
- 程序员跳槽一次到底能涨多少?今天带你见识下跳槽天花板
- 行动诠释价值,城联优品韩董事长出席广东英德抗洪捐赠公益活动会
- TX2/Linux下can总线的接收与发送详解!(回环测试)
- 汇编SHR、SHL、SAR、SAL、ROL、ROR、RCL、RCR指令
- 要脱大家一起脱:网络实名制与官员财产透明化
- 从万物静默到声情并茂:百度输入法的AI发声计划
- 论文笔记30 -- (视频压缩)【CVPR2021】FVC: A New Framework towards Deep Video Compression in Feature Space
- 搜素引擎与社会责任的关系
热门文章
- 百度凤巢面试复盘(策略研发方向[实习])
- STM32CubeMX——LED定时闪烁和输出PWM波
- Mac 电脑四大类生产力软件,你还缺少哪些?
- 手机壳定制壁纸下载小程序全过程安装搭建教程
- 除号java_【除号66】loadrunner-java虚拟用户小结 (准备篇)
- 香港公司、香港离岸公司和岛屿公司3者区别
- Linux 之十七 Ubuntu 22.04 配置内核版本、GRUB 引导、远程桌面
- Openstack-T 之Nova组件
- 2019级计算机学院数据结构编程作业,数据结构上机实验报告
- HTML中em标签的用法