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

 

 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一一对应起来的话,就会简单很多。


你可能感兴趣的:(Spring学习笔记四(AOP中的通知参数和注解开发))