1.前言
上一篇博客介绍了如何通过AOP来切入我们想实现的公共性的功能,这篇博客来讲一下,当我们拦截到方法后,如何来获取通知参数。这也是AOP的精髓所在,通过AOP可以实现偷梁换柱的功能。我们把原来要执行的方法的参数获取到,然后换一套参数执行。下面来跟着我看一下吧!
2.AOP的通知参数
有时我们想通过AOP拦截到我们要加入通知的切点类的参数,通俗的说就像拿到拦截的方法的参数值,然后如果不合适的话,我们可以修改一下或者做一些其他的操作。例如用户登录的功能,我们可以把验证身份的功能抽离出来,然后在AOP中拦截到登陆方法中的参数,通过判断用户名来决定做下一步的操作。那么如何来取出用户名呢。
如果需要在通知方法中获取原始方法的调用参数,需要在通知方法的第一个形参位置声明JoinPoint类型的参数,使用该参数调用getArgs()方法可以获得原始方法的调用参数列表Object[]
<span style="font-size:18px;">package com.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; //通知类 public class MyAdvice { public void before(JoinPoint jp,String a,int b){ //Object[] objs = jp.getArgs(); //System.out.println("before......"+objs[0]+","+objs[1]); System.out.println("before......"+a+","+b); } public void after(JoinPoint jp){ System.out.println("after......"); } public void afterReturning(JoinPoint jp,Object abc){ System.out.println("afterReturning......"+abc); } public void afterThrowing(JoinPoint jp){ System.out.println("afterThrowing......"); } //具有公共性的功能 public Object fn(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("aaaaaaa"); //获取到执行的参数 Object[] obj= pjp.getArgs(); for (Object lb:obj) { System.out.println(lb); } //进行偷梁换柱的功能 Object ob= pjp.proceed(new Object[]{new Integer(6),new Integer(9)}); System.out.println("bbbbbbbbbbbbbbb"); return ob; } } </span>注意:所有通知都可以通过JoinPoint获得通知的参数,但是只有around类别才可以执行替代拦截方法。
3.AOP通知返回值
1.只有afterReturning 与 around可以获取方法的返回值
2.afterReturning:在配置中设置returning属性,值是变量名的值,与方法的形参进行对应
<aop:after-returning method="afterReturning"returning="abc"/>
publicvoid afterReturning(JoinPoint jp,Object abc){
System.out.println("afterReturning......"+abc);
}
3.around:直接通过程序中的原始方法调用获取,该方法返回值即为原始方法的返回值
publicObject around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("aroundbefore......");
//调用原始方法
Objectobj = pjp.proceed();
System.out.println("around after......"+obj);
return obj; 说明:对原始方法拦截后,最终的运行返回值取决于这里
}
4.AOP的注解开发
注解开发也特别的简单,下面给出一个实例,与平常的XML配置类似
<span style="font-size:18px;">package cn.itcast.aop.annotation; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; //定义切面类 @Aspect public class BookAdvice { //切面 @Pointcut("execution(* cn.itcast.aop.annotation.BookService.add(..))") private void pt(){} //切点的顺序 @Before("BookAdvice.pt()") public void before(JoinPoint jp){ System.out.println("before running......"); } @After("BookAdvice.pt()") public void after(){ System.out.println("after running......"); } @AfterReturning(value="BookAdvice.pt()",returning="abc") public void afterReturning(Object abc){ System.out.println("afterReturning running......"+abc); } @AfterThrowing(value="execution(* cn.itcast.aop.annotation.BookService.add(..))",throwing="t") public void afterThrowing(Throwable t){ System.out.println(t); System.out.println("afterThrowing running......"); } @Around("execution(* cn.itcast.aop.annotation.BookService.add(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("around before running......"); Object retValue = pjp.proceed(); System.out.println("around after running......"); return retValue; } } </span>注意:上述的配置与XML一一对应起来的话,就会简单很多。
版权声明:本文为博主原创文章,未经博主允许不得转载。