Spring返回通知、异常通知和环绕通知

 Spring返回通知、异常通知和环绕通知

 一、说在前面

 加入的jar包,配置的aop命名空间,以及基于注解的相关配置和上文中前置通知和后置通知完全一样,在这里就不在赘述。

 二、实现代码如下:

1、返回通知

	//返回通知:在代码正常执行之后返回的代码
	//返回通知是可以访问到方法的返回值的。
	@AfterReturning(value="execution(* com.at.aop.ArithmeticCalculator.*(..))",returning="result")
	public void afterReturning(JoinPoint joinPoint,Object result){
		String methodName = joinPoint.getSignature().getName();
		System.out.println("返回通知方法 "+methodName+" 结果为 "+result);
	}

2、异常通知

        //异常通知
	@AfterThrowing(value="execution(* com.at.aop.ArithmeticCalculator.*(..))",throwing="ex")
	public void afterThrowing(JoinPoint joinPoint,Exception ex){
		String methodName = joinPoint.getSignature().getName();
		System.out.println("异常通知方法 "+methodName+" 发生的异常为 "+ex);
	}

3、环绕通知

	/*环绕通知需要携带 ProceedingJoinPoint 类型的参数
	 * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是够执行目标方法
	 * 并且环绕通知必须有返回值,返回值就是目标方法的返回值。
	 */
	@Around("execution(* com.at.aop.ArithmeticCalculator.*(..))")
	public Object aroundMethod(ProceedingJoinPoint pjp){
		
		Object result = null;
		String methodName = pjp.getSignature().getName();
		
		try {
			//前置通知
			System.out.println("环绕通知中的前置通知方法 "+methodName+" 开始于参数 "+Arrays.asList(pjp.getArgs()));
			//执行目标
			result = pjp.proceed();
			//返回通知
			System.out.println("环绕通知中的返回通知方法 "+methodName+" 结果为 "+result);
		} catch (Throwable e) {
			//异常通知
			System.out.println("环绕通知中的异常通知方法 "+methodName+" 结果为 "+e);
			throw new RuntimeException(e);
		}
		//后置通知
		System.out.println("环绕通知中的后置通知方法 "+methodName+" 结束了 ");
		
		return result;
	}

4、applicationContext.xml配置文件


	
	
	
	
	
	


5、测试函数
package com.at.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAspect {

	public static void main(String[] args) {
		
		//1、创建spring的ioc容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		//2、从ioc容器中获取bean的事例
		ArithmeticCalculator ac = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
		
		//3、使用bean
		int result = ac.add(3, 6);
		System.out.println("result "+result);
		
		int result2 = ac.div(12, 0);
		System.out.println("result "+result2);
	}
}

6、测试结果
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
环绕通知中的前置通知方法 add 开始于参数 [3, 6]
前置通知方法 add 开始 [3, 6]
环绕通知中的返回通知方法 add 结果为 9
环绕通知中的后置通知方法 add 结束了 
后置通知方法 add 结束 
返回通知方法 add 结果为 9
result 9
环绕通知中的前置通知方法 div 开始于参数 [12, 0]
前置通知方法 div 开始 [12, 0]
环绕通知中的异常通知方法 div 结果为 java.lang.ArithmeticException: / by zero
后置通知方法 div 结束 
异常通知方法 div 发生的异常为 java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
Exception in thread "main" java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
	at com.at.aop.LoggingAspect.aroundMethod(LoggingAspect.java:71)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy11.div(Unknown Source)
	at com.at.aop.TestAspect.main(TestAspect.java:20)
Caused by: java.lang.ArithmeticException: / by zero
	at com.at.aop.ArithmeticCalculatorImpl.div(ArithmeticCalculatorImpl.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
	at com.at.aop.LoggingAspect.aroundMethod(LoggingAspect.java:65)
	... 19 more


By luoyepiaoxue2014
微博地址:http://weibo.com/luoyepiaoxue2014  点击打开链接

你可能感兴趣的:(Spring)