标签:pkg 执行 序号 system div short 逻辑运算 otn frame
@AspectJ可以使用切点函数定义切点, 我们还可以使用逻辑运算对切点进行复合运算得到复合的切点. 我们还可以对切点进行命名, 从而可以复用切点.当一个连接点匹配多个切点时, 需要考虑增强织入的顺序.还有一个在前面提到过的问题就是, 如何访问在增强中访问连接点上下文信息.下面对这几方面进行学习.
使用切点进行复合运算, 使得我们能够拥有强大的表达切点的能力.例子如下:
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子类的所有连接点的切点.
在前面的例子中, 切点直接定义在增强方法处, 这种切点声明方式称作为匿名切点.匿名切点只能在声明处使用.如果想在其他地方重用一个切点, 我们可以通过@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...");
}
如果一个连接点匹配了多个切点,切点对应的增强在连接点上的织入顺序是如何确定的呢?这个问题要看情况:
(1). 如果增强是在同一个切面中定义的, 则织入顺序按增强定义的顺序进行织入
(2).如果增强是在不同切面中定义的, 但是这些切面类都实现了org.springframework.core.Ordered接口, 则由接口中方法的顺序号织入, 顺序号小的小织入.
(3). 如果增强是在不同切面中定义的, 但是又没有实现Ordered接口, 则增强的织入顺序是不确定的.
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进阶
标签:pkg 执行 序号 system div short 逻辑运算 otn frame
原文地址:http://www.cnblogs.com/NewMan13/p/6002325.html