一、简介
之前几篇文章简单了说明了aop的一些基本的配置及使用,可以发现前面的文章中并没有给出aop获取方法执行结果和获取异常栈的方法,其实AOP中本身自带了两种通知,用来获取方法执行结果与异常栈。
- (一)@AfterReturning
不同于@After注解,@AfterReturning注解虽然也是在方法执行之后执行,但是利用它可以获取方法的执行结果。@AfterReturning有一个returning
的属性,用来标识,接收方法执行结果的变量,如下面的示例所示,用result(这个变量名是自定义的)参数去接收方法的执行结果,并在最终通知方法中返回。
切面类LoginAspect
LoginServiceimport org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import java.util.Arrays; /** * 切面类 * @Aspect 注解用来标识 */ @Aspect @Component public class LoginAspect { /** * 定义一个切点 */ @Pointcut("execution(public * com.haici.spring.demo.aop.LoginService.login(java.lang.String, java.lang.String))") public void pointcut() { } /** * execution(* *.*(..)) 切入点表达式 * @Before 前置通知 在方法执行前运行该方法 * 通知方法 前置通知 */ @Before(value = "pointcut()") public void beforeNotice(JoinPoint point){ System.out.println("执行前置通知 入参 = " + Arrays.toString(point.getArgs())); } /** * execution(* *.*(..)) 切入点表达式 * @After 后置通知 在方法执行之后运行 * 通知方法 后置通知 */ @After("pointcut()") public void afterNotice(JoinPoint point){ System.out.println("执行后置通知 "); } /** * @AfterReturning 与 @After的不同之处在于 @After 无法获取被代理对象的方法的执行结果 * returning 属性用来标识接收方法返回值的变量 * @param point */ @AfterReturning(value = "pointcut()", returning = "result") public String afterReturningNotice(JoinPoint point, String result){ System.out.println("执行AfterReturning通知 入参 = " + Arrays.toString(point.getArgs())); return result; } /** * @AfterThrowing 能够在发生异常后捕获异常信息 * throwing 属性用来标识接收方法返回的异常信息的变量 * @param point */ @AfterThrowing(value = "pointcut()", throwing="exception") public void afterReturningNotice(JoinPoint point, Exception exception){ System.out.println("执行AfterThrowing通知 入参 = " + Arrays.toString(point.getArgs()) + " 异常信息是" + exception.getCause()); } }
测试类@Service public class LoginService { public String login(String userName, String password){ System.out.println("用户"+userName+"登录"); return "success"; } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:application.xml") public class LoginServiceTest { @Autowired private LoginService loginService; @Test public void test(){ String result = loginService.login("zhangsan", "1234"); System.out.println(loginService.getClass()); //会发现打印出来的类型是代理对象的类型 而不是LoginService的Class System.out.println(result); //方法的返回结果 如果没有使用@AfterReturning 获取出来的result会是一个null } } ```
- (二)@AfterThrowing
如果是需要获取方法执行的异常栈信息则需要通过@AfterThrowing才能实现
示例在上面