您的位置:首页 > 编程语言 > Java开发

Spring学习笔记四(AOP中的通知参数和注解开发)

2015-08-11 15:46 821 查看
 

 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一一对应起来的话,就会简单很多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: