测试基于以下代码
1.首先是创建切面
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(* org.sang.aop.service.*.*(..))")
public void pc1() {
}
@Before(value = "pc1()")
public void before(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println(name + "方法开始执行...");
}
@After(value = "pc1()")
public void after(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println(name + "方法执行结束...");
}
@AfterReturning(value = "pc1()", returning = "result")
public void afterReturning(JoinPoint jp, Object result) {
String name = jp.getSignature().getName();
System.out.println(name + "方法返回值为:" + result);
}
// @Around("pc1()")
// public Object around(ProceedingJoinPoint pjp) throws Throwable {
// System.out.println("进入环绕通知");
//
// //pjp.proceed();
// System.out.println("退出环绕通知");
// return "返回的是环绕通知的返回值";
// }
}
2.然后是UserService类
@Service
public class UserService {
public String deleteUserById(Integer id) {
System.out.println("delete...");
return 返回的是deleterUserById的返回值;
}
}
最后是在Controller中创建接口,调用UserService中的deleteUserById方法:
@RestController
public class UserController {
@Autowired
UserService u=new UserService();
@RequestMapping("/deleteUserById")
public String deleteUserById(){
return u.deleteUserById(1);
}
}
然后就可以在浏览器上输入localhost:8080/deleteUserById来进行测试了,本次所有测试不包含对异常通知的测试
测试一:在上面切面的代码块中,我首先是将环绕通知给注释掉的,直接看控制台的打印结果:![在这里插入图片描述](https://img-blog.csdnimg.cn/20210523172452620.png#pic_center)
总结:在没有环绕通知的情况下,执行顺序是:前置通知,deleteUserById方法,后置通知,返回通知
测试二:接下来对环绕通知取消注释:
@Around("pc1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("进入环绕通知");
//pjp.proceed();
System.out.println("退出环绕通知");
return "返回的是环绕通知的返回值";
}
其中pjp.proceed()是在调用deleteUserById方法,我这先注释掉,然后来看看控制台结果:
总结:由图中可以看出先环绕通知,再后置通知,最后返回通知,并没有打印"delete…",而且,返回值变成了环绕通知的返回值,还有,也没有执行前置通知,所以,可以得出结论,环绕通知存在的时候,通过在浏览器上输入localhost:8080/deleteUserById调用deleteUserById方法并不会真正执行deleteUserById的方法体,而是转到环绕通知,所有也就没有前置通知,但因为业务要求,总归要执行deleteUserById的方法体的,所以需要在环绕通知里加入pjp.proceed()来执行deleteUserById的方法体,来看接下来的测试:
测试三:环绕通知里执行pjp.proceed():
@Around("pc1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("进入环绕通知");
pjp.proceed();
System.out.println("退出环绕通知");
return "返回的是环绕通知的返回值";
}
总结:图中可以看出,各个通知的执行顺序,首先是执行环绕通知,在环绕通知执行过程中(也就是还在环绕通知方法里面),因为调用了deleteUserById方法,所以执行了前置通知,然后就是环绕通知结束了,才调用后置通知,最后是返回通知。
返回值也是环绕通知的返回值(个人猜测:环绕通知的return后于deleteUserById方法体的return,所以覆盖了)。
以上就是本次测试全部内容,本人后端小萌新一个,有任何说错的地方欢迎大家在评论区指出,一起学习进步。