AOP中的一些概念
切点表达式:
*
匹配一个或多个字符串,execution(public int com.xiaol.MyMath*.*(int, int))
匹配任意一个参数, execution(public int com.xiaol.MyMath*.*(int, *))
只能匹配一层路径
权限位不能用*, 权限位不写就行 public [可选的]
...
匹配任意多个参数,任意参数类型,execution(public int com.xiaol.MyMath*.*(...))
匹配任意多层路径
五种通知
try{
@Before
method.invoke
@AfterReturning
}catch(){
@AfterThrowing
}finally{
@After
}
@Before
在目标方法之前运行, 在通知方法运行时,可以通过参数JointPoint那个方法运行的相关信息
@After("")
public static void afterFunction(JoinPoint jp){
System.out.println(jp.getSignature().getName())
}
@After
在目标方法之后运行
@AfterReturning
在目标方法正常返回之后运行, 除了用JoinPoint来获取方法的相关信息外,还需要告诉spring用那个参数来接收返回值
public static void afterReturnFunction(JoinPoint jp, Object object)
@AfterThrowing
在目标方法抛出异常后运行,除了用JoinPoint来获取方法的相关信息外,还需要告诉spring用那个参数来接收异常, 同时本类里的异常是要抛出去的,否则,外层接收不到异常
public static void throwingFunction(JoinPoint jp, Exception e)
@Around
环绕通知,(四合一的通知) ProceedingJoinPoint可以拿到相关的上下文信息
public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
Object[] args = pjp.getArgs();
Object proceed;
try{
proceed = pjp.proceed(args);
}catch{
}finally{
retrun proceed
}
}
可以提取公共的切点:
1.随便声明一个没有实现的返回void的空方法,在上面用@Pointcut加公共的切点声明
2.其他方法用这个方法来声明切点
@Pointcut("execution(public int com.xiaol.*.*(...))")
public void test(){}
@Before("test()")
public beforeFuntciont(){
System.out.println();
}
切面类上可以加一个@Order的注解,用以表示当一个方法同时被多个切面切的时候,这些切面的执行顺序,值越小,优先级越高,如果值相同,就按字母顺序排列