AOP五种增强

1.前置增强
前置增强用@Before注解标识,例如:

@Before("execution(public int mul(int,int))")
	public void before(JoinPoint joinPoint) {
		Object target = joinPoint.getTarget();
		Object[] params = joinPoint.getArgs();
		String methodName = joinPoint.getSignature().getName();
		System.out.println(target.getClass().getName()+":The "+methodName+" method begins.");
		System.out.println(target.getClass().getName()+":Parameters of the "+methodName+" method: ["+params[0]+","+params[1]+"]");
		System.out.println("before");
	}

其结果特征就是前置增强方法先于目标方法执行结束:
在这里插入图片描述
“---->1”是目标函数执行的结果


2.后置增强
后置增强以@After注解标识
例如:

@After("execution(public int mul(..))")
	public void after(JoinPoint joinPoint) {
		
		Object target = joinPoint.getTarget();
		String name = joinPoint.getSignature().getName();
		System.out.println(target.getClass().getName()+" :the "+name+" ends");
		System.out.println("after");
	}

其结果特征是后置增强方法在目标方法后执行:
在这里插入图片描述
红线下面那两行是后置增强方法执行的结果


3.返回增强
返回增强以@AfterReturning注解为标识
例如:

@AfterReturning(value="execution(public int mul(int,int))",returning="re")
	public void afterReturning(JoinPoint joinPoint,int re) {
		Object target = joinPoint.getTarget();
		System.out.println(target.getClass().getName()+"返回增强"+" 结果 "+re);
	}

其中的returning="re"是规定把返回值传递给public void afterReturning(JoinPoint joinPoint,int re)中的re.
结果特征为:
结果特征为:返回增强并不一定执行,当目标函数抛出异常时它不会执行

在这里插入图片描述
从上图可以发现,当目标函数不抛出异常时执行顺序为:前置增强—>目标函数----->后置增强------>返回增强

当目标函数抛出异常时如下:前置增强—>目标函数----->后置增强
在这里插入图片描述
上图最后一行是接下来要说的异常增强


4异常增强
异常增强以@AfterThrowing注解为标识
例如:

@AfterThrowing(value="execution(public int mul(int,int))",throwing="e")
	public void afterThrowing(JoinPoint joinPoint,Exception e) {
		Object target = joinPoint.getTarget();
		System.out.println(target.getClass().getName()+"出现异常:"+e.getMessage());
	}

使用这个增强时有如下注意事项:
(1.)目标函数要抛出异常,并且抛出的异常是public void afterThrowing(JoinPoint joinPoint,Exception e)中规定捕获的异常的子类,或者是同样的异常,这里可以用数学中的交集理解:
在这里插入图片描述
(2.)当目标函数不抛出异常时,可以执行返回增强,此时异常增强不执行;当目标函数抛出异常时,返回增强不执行,异常增强可以执行。故二者不会同时执行

总之:执行顺序为 前置增强----->目标函数------->后置增强-------->返回增强跟异常增强二选一


5.环绕增强
该增强以@Around注解为标识,在环绕增强中可以实现上述四种增强
例如:

@Around("execution(public int *(..))")
	public Object around(ProceedingJoinPoint jp) {//ProceedingJoinPoint是JoinPoint的子类
		Object target = jp.getTarget();
		Object[] params = jp.getArgs();
		String methodName = jp.getSignature().getName();
		Object result = null;
		try {
			try {
				//前置增强
				System.out.println(target.getClass().getName()+":The "+methodName+" method begins.");
				System.out.println(target.getClass().getName()+":Parameters of the "+methodName+" method: ["+params[0]+","+params[1]+"]");
				System.out.println("before");
				result = jp.proceed();
			} finally {
				//后置增强
				System.out.println(target.getClass().getName()+" :the "+methodName+" ends");
				System.out.println("after");
			}
			//返回增强
			System.out.println(target.getClass().getName()+"返回增强"+" 结果 "+result);
		} catch (Throwable e) {
			//异常增强
			System.out.println(target.getClass().getName()+"出现异常:"+e.getMessage());
			e.printStackTrace();
		}
		System.out.println("环绕+"+result);
		return result;
	}

当目标函数不抛出异常时:结果如下
在这里插入图片描述

当目标函数抛出异常时:结果如下
在这里插入图片描述
打个比方:环绕增强可以看作是蛋壳,目标函数看作是蛋壳里的内容物。

发布了74 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/naruhina/article/details/96152997
今日推荐