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配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
	<!-- 配置自动扫描的包 -->
	<context:component-scan base-package="com.at.aop"></context:component-scan>
	
	<!-- 使AspjectJ 注解起作用:自动为匹配的类生产代理对象 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

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  点击打开链接

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值