一.Advice注解分类:
切面表达式也可以直接写在Advice通知注解中
1.@Before:
前置通知,方法执行之前执行
2.@After(finally):
后置通知,方法执行之后执行,无论成功执行还是抛出异常
3.@AfterReturning:
◆返回通知,方法成功执行之后执行,异常或者错误不执行
◆可以获取方法返回值
//Advice通知:@AfterReturning(value="切入点",returning="接收返回值的变量名"),接收返回值的变量名必须和通知方法的参数名一致,类型必须能互转
@AfterReturning(value="exTest4()",returning="user")
public void useExTest1(String user){
System.out.println("...匹配public方法的切面:"+user);
}
4.@AfterThrowing:
异常通知,方法抛出异常之后才执行,成功时不执行
5.@Around:
环绕通知,包括以上四中注解!能决定目标方法是否执行和执行时间。
1.Around包含以上四种注解功能详解:
@Around("point()")
public void exec(ProceedingJoinPoint point) throws Throwable{
System.out.println("...............Before(此处执行的代码相当于-前置通知)...............");
try{
point.proceed();//有此代码,被切入的方法体才会执行,如果被切入的方法有返回值,则返回值为null,见3
System.out.println("...............AfterReturning(此处执行的代码相当于-返回通知)...............");
}catch(Exception e){
System.out.println("...............AfterThrowing(此处执行的代码相当于-异常通知)...............");
}finally{
System.out.println("...............After1(此处执行的代码相当于-后置通知).................");
}
System.out.println("...............After2(此处执行的代码相当于-后置通知).................");
}
2.使用@Around时可以使用ProceedingJoinPoint类作为参数
@Around("point()")
public void exec(ProceedingJoinPoint point) throws Throwable{
//调用目标方法(被切入方法)
point.proceed();
//调用目标方法,使用此参数覆盖调用时传的参数,如果参数列表或类型不对,调用失败
Object[] objs = {1,1};
point.proceed(objs);
//获取目标方法调用时传入的参数列表
Object[] args = point.getArgs();
//获取目标方法所在类的对象
Object target = point.getTarget();
//获取当前执行的对象
Object thise = point.getThis();
//获取连接点的签名(Signature为顶级父接口,其有很多子接口,并子接口有各自实用的方法,可看:AspectJ.CHM)
Signature signature = point.getSignature();
//获取被切入方法的类的Class对象(结果:clazz=class com.tiglle.manage.test.service.TestService||class com.tiglle.manage.test.service.UserService)
Class clazz = point.getSignature().getDeclaringType();
//获取被切入方法的类的全路径类名(className=com.tiglle.manage.test.service.TestService||com.tiglle.manage.test.service.UserService)
String className = point.getSignature().getDeclaringTypeName();
//获取被切入方法的方法名(结果:str=test||user)
String methodName = point.getSignature().getName();
}
3.改变目标方法的返回值(需要注意又返回值的目标方法)
◆如果目标方法有返回值,但Around通知方法为void,那么目标方法被切入执行完后,返回值为null!!!
//如果目标方法有返回值,但Around通知方法为void,那么目标方法被切入执行完后,返回值为null!!!
@Around("execution(* *(..))")
public void exec(ProceedingJoinPoint point) throws Throwable{
System.out.println("around");
point.proceed();
}
◆改变目标方法的返回值
//如果目标方法有返回值,但Around通知方法为void,那么目标方法被切入执行完后,返回值为null!!!
@Around("execution(* *(..))")
public Object exec(ProceedingJoinPoint point) throws Throwable{
System.out.println("around");
Object returnner = point.proceed();
return returnner+":被改变追加的返回值";
}
此时,目标方法返回值将会被追加":被改变追加的返回值";
6.获取方法的参数,以上注解都能用
//获取方法的参数列表(value="exTest4() && args(id,age)")
@AfterReturning(value="exTest4() && args(id,age)")
public void useExTest1(Long id,Integer age){
System.out.println("...匹配public方法的切面:"+id+":"+age);
}
7.获取方法的参数,以及方法的返回值。同时获取只能使用@AfterReturning注解
//方法的返回值和参数同时获取,只能使用@AfterReturning注解,并且返回值在通知方法的前面,参数在后面
@AfterReturning(value="exTest4() && args(id,age)",returning="user")
public void useExTest1(User user,Long id,Integer age){
System.out.println("...匹配public方法的切面:"+id+":"+age+":"+user);
}