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