基于@AspectJ和schema的aop(四)---@AspectJ进阶
@AspectJ可以使用切点函数定义切点, 我们还可以使用逻辑运算对切点进行复合运算得到复合的切点. 我们还可以对切点进行命名, 从而可以复用切点.当一个连接点匹配多个切点时, 需要考虑增强织入的顺序.还有一个在前面提到过的问题就是, 如何访问在增强中访问连接点上下文信息.下面对这几方面进行学习.
1.对切点进行复合运算
使用切点进行复合运算, 使得我们能够拥有强大的表达切点的能力.例子如下:
package com.bao.bao.aspectj; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * Created by xinfengyao on 16-10-26. */ @Aspect public class TestAspect { // (1) @After("within(com.bao.bao.aspectj.*) && execution(* greetTo(..))") public void greetToFun() { System.out.println("...greetToFun() executed..."); } //(2) @Before("!target(com.bao.bao.aspectj.NaiveWaiter) && execution(* serveTo(..))") public void noteServeInNaiveWaiter() { System.out.println("...notServeInNaiveWaiter() executed..."); } // (3) @AfterReturning("target(com.bao.bao.aspectj.Waiter) || target(com.bao.bao.aspectj.Seller)") public void waiterOrSeller() { System.out.println("...waiterOrSeller() executed..."); } }
在(1)处, 我们通过&&逻辑运算定义了一个匹配com.bao.bao.aspectj包中所有的greetTo()方法的切点.在(2)处, 我们通过!和&&逻辑运算定义了一个匹配serveTo()方法, 并且该方法不是NaiveWaiter或者其子类中的方法.在(3)我们通过||逻辑运算定义了一个匹配Waiter子类或者Seller子类的所有连接点的切点.
2.命名切点
在前面的例子中, 切点直接定义在增强方法处, 这种切点声明方式称作为匿名切点.匿名切点只能在声明处使用.如果想在其他地方重用一个切点, 我们可以通过@Pointcut注解以及切面类方法对切点进行命名.如下:
package com.bao.bao.aspectj; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; /** * Created by xinfengyao on 16-10-26. */ @Aspect public class TestNamePointcut { @Pointcut("within(com.bao.bao.*))") private void inPackage(){ } @Pointcut("execution(* greetTo(..))") protected void greetTo() { } @Pointcut("inPackage() && greetTo()") public void inPkgGreetTo() { } }
命名切点定义好后, 我们就可以在定义切面时通过名称引用切点.如下所示:
@Before("TestNamePointcut.inPkgGreetTo()") public void pkgGreetTo() { System.out.println("...pkgGreetTo() executed..."); } @Before("!target(com.bao.bao.aspectj.NaiveWaiter) && TestNamePointcut.inPkgGreetTo()") public void pkgGreetToNotNaiveWaiter() { System.out.println("...pkgGreetToNotNaiveWaiter() executed..."); }
3.增强织入的顺序
如果一个连接点匹配了多个切点,切点对应的增强在连接点上的织入顺序是如何确定的呢?这个问题要看情况:
(1). 如果增强是在同一个切面中定义的, 则织入顺序按增强定义的顺序进行织入
(2).如果增强是在不同切面中定义的, 但是这些切面类都实现了org.springframework.core.Ordered接口, 则由接口中方法的顺序号织入, 顺序号小的小织入.
(3). 如果增强是在不同切面中定义的, 但是又没有实现Ordered接口, 则增强的织入顺序是不确定的.
4.如何访问连接点的信息
AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象, 如果是环绕增强, 使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口, 使用任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息.下面看下这两个接口的主要方法:
(1) JoinPoint
String toShortString(); String toLongString(); Object getThis(); 获取代理对象本身 Object getTarget(); 获取连接点所在的目标对象 Object[] getArgs(); //获取连接点方法运行时的入参列表 Signature getSignature(); // 获取连接点的方法签名对象
(2) ProceedingJoinPoint
Object proceed() throws Throwable; //通过反射执行目标对象的连接点处的方法 Object proceed(Object[] var1) throws Throwable;
基于@AspectJ和schema的aop(四)---@AspectJ进阶的更多相关文章
- 基于@AspectJ和schema的aop(二)---@AspectJ基础语法
@AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...
- 基于@AspectJ和schema的aop(一)
在前面我们使用Pointcut和Advice描述切点和增强, 并使用Advisor整合两者描述切面.@AspectJ使用注解来描述切点和增强.两者使用的方式不同, 但是在本质上都是一样的. 我们还是用 ...
- spring3: schema的aop与Aspectj的aop的区别
schema的aop如下: 接口: package chapter6.service; public interface IHelloAroundService { public void sayAr ...
- (spring-第19回【AOP基础篇】)基于AspectJ和Schema的AOP
基于AspectJ就是基于@AspectJ注解,基于Schema就是全部依靠配置文件.那么首先要了解Java注解. Java注解初探 在JDK5.0中,我们可以自定义标签,并通过Java语言的反射机制 ...
- 基于@AspectJ和schema的aop(三)---切点函数详解
切点函数是AspectJ表达式语言的核心, 也是使用@AspectJ进行切面定义的难点.本小节我们通过具体的实例对切点函数进行深入学习. 1.@annotation() @annotation()表示 ...
- Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较
本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...
- Spring中基于AOP的@AspectJ
以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...
- Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现
转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...
- Spring 中基于 AOP 的 @AspectJ
Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...
随机推荐
- UEditor和CKEditor配置上传图片,视频,附件
UEditor: http://blog.sina.com.cn/s/blog_8bb128230102v12x.html CKEditor:http://blog.sina.com.cn/s/blo ...
- .NET: WPF Binding对数据的校验和转换以及多路Binding
一.校验 一般需要对target上的值进行校验. xaml: <Window x:Class="WpfApplication1.MainWindow" xmlns=" ...
- vs2010打包系统必备选择.net framework 3.5sp1编译错误的解决方法
利用visual studio 2010进行打包程序,默认安装的是Framework 4.0,如果需要将3.5sp1打包到系统中一起安装(选择了"从与我的应用程序相同的位置下载系统必备组件& ...
- 安装Git
因为我的开发环境是Windows,那么在windows下安装Git就简单很多了.首先在,从http://msysgit.github.io/下载Git的安装程序,然后按默认选项安装即可. 安装成功之后 ...
- 新发现了一个编辑器HBuilder,感觉蛮好的,关键是国产软件。
http://www.dcloud.io/
- 查看linux僵尸进程
top ps -A -o stat,ppid,pid,cmd | grep -e '^[zZ]' kill -HUP 进程号
- 使用 Delphi Xe 的 TDictionary
原本一直使用 TList, 将定义的一个个 Record 保存在TList 里面, 为了能把某些对象管理起来, 例如一个类的 n 多实例,可以进行索引.查找.释放等 今天刚看到原来已经有了一个叫 TD ...
- vsftp不同帐号的目录和权限
搭建FTP服务器,供虚拟用户使用,实现不同用户具有不同家目录和权限. 1.用户peter的家目录为/var/ftp/vuserdir/peter,他只有下载权限,没有其他权限(创建目录.重命名.删除. ...
- 160920、springmvc上传图片不生成临时文件
springMVC上传图片时候小于10k不会再临时目录里面生成临时文件,需要增加一个配置 <property name="maxInMemorySize" value=&qu ...
- DIV设置了固定宽高出现文字(文本)的不能自动换行
如果你的div设置了固定的width和height,有时会出现文字不能自动换行的情况 查过相关资料后才知道,只有英文文本才会出现不能自动换行的情况,(中文不存在)而原因是因为英文文本之间没有加空格,浏 ...