Spring AOP 四大通知
Spring AOP 四大通知
Spring 3.X 以前
1.前置通知,实现 MethodBeforeAdvice 接口,重写
public void before(Method method, Object[] args, Object target) throws Throwable方法
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class TestMethodBeforeAdvice implements MethodBeforeAdvice {
/** arg0 方法
* arg1 参数
* arg2 操作对象
* */
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("前置通知:----》方法:"+arg0.getName()+"传入参数"+arg1+"操作象"+arg2);
}
}
2.后置通知,实现 AfterReturningAdvice 接口,重写
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable 方法
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class TestAfterReturningAdvice implements AfterReturningAdvice{
/**
* arg0:return 的返回值
* arg1:执行的方法对象
* arg2:方法执行中传递过来的参数
* arg3:执行方法的对象
*/
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("后置通知:----》方法:"+arg1.getName()+"返回值:"+arg0+"执行方对象:"+arg3);
}
}
3.环绕通知, 实现 MethodInterceptor 接口,重写
public Object invoke(MethodInvocation invocation) throws Throwable 方法
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class TestMethodinterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod() ; //方法
Object[] objs = invocation.getArguments() ; //参数
Object obj = invocation.getThis() ; //操作对象
System.out.println("环绕通知:-----》 开始: 方法:"+method.getName()+"传入的参数:"+objs+" 操作对象:"+obj);
Object result = invocation.proceed() ; //放行
System.out.println("环绕通知:-----》 结束: 返回值:"+result);
return result ;
}
}
4.异常通知,实现 ThrowsAdvice 接口,重写
public void afterThrowing(Method m, Object args, Object target,Throwable e) 方法
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class TestThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method m, Object args, Object target, Throwable e) {
System.out.println("异常通知:方法"+m.getName()+"发生异常,"+e.getMessage());
System.exit(0);
}
}
注意:查看ThrowsAdvice源码会发现这个接口里面没有定义方法,但是这个方法必须这么写,
Spring 3.X 以后版本
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class TestAdvice {
public void before(JoinPoint joinPoint){ //前置通知
System.out.println("操作者"+joinPoint.getTarget()+"参数 "+joinPoint.getArgs()[0]);
System.out.println("*********************前置通知*********************");
}
//后置通知:当方法执行完会触发,出错则不执行
public void afterReturning(JoinPoint joinPoint,Object obj){
System.out.println("后置通知");
System.out.println("返回结果:"+obj);
}
//最终通知
public void after(JoinPoint joinPoint){
System.out.println("最终通知");
System.out.println("调用的方法"+joinPoint.getSignature());
}
//异常通知
public void throwAdvice(Exception exception){
System.out.println("--------异常通知--------");
System.out.println("异常消息"+exception.getMessage());
}
//环绕通知
public Object around(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("环绕通知开始");
try {
Object obj = proceedingJoinPoint.proceed() ;
System.out.println("环绕通知结束");
return obj ;
} catch (Throwable e) {
e.printStackTrace();
}
return null ;
}
}
配置信息
<!--Spring3.X以前-->
<!--后置通知-->
<bean id="afterAdvice" class="com.spring.advice.TestAfterReturningAdvice"/>
<!--前置通知-->
<bean id="beforeAdvice" class="com.spring.advice.TestMethodBeforeAdvice"/>
<!--环绕通知-->
<bean id="interceptorAdvice" class="com.spring.advice.TestMethodinterceptor"/>
<!--异常通知-->
<bean id="throwsAdvice" class="com.spring.advice.TestThrowsAdvice"/>
<!--Spring3.X以后整合-->
<bean id="advice" class="com.spring.advice.TestAdvice"/>
<!-- AOP设置 -->
<aop:config>
<aop:pointcut expression="execution(* com.spring.service.*.*(..))" id="mycut"/>
<aop:advisor advice-ref="afterAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="interceptorAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="throwsAdvice" pointcut-ref="mycut"/>
<!-- 新版本 -->
<aop:aspect ref="advice">
<aop:before method="before" pointcut-ref="mycut"/>
<aop:after-returning method="afterReturning" returning="obj" pointcut-ref="mycut"/>
<aop:after method="after" pointcut-ref="mycut"/>
<aop:after-throwing method="throwAdvice" throwing="exception" pointcut-ref="mycut"/>
<aop:around method="around" pointcut-ref="mycut"/>
</aop:aspect>
</aop:config>
两种方法:
Spring3.X版本以前写法思路更清晰,新版本,虽然把4个通知整合在了一起,但是,如果业务复杂的话,通知较多建议分开写,
两种方法区别不是很大,具体还得开需求
expression的value值
任意公共方法的执行:
execution(public * *(..))
任何一个以“set”开始的方法的执行:
execution(* set*(..))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
若要转载,请标明此处
Spring AOP 四大通知的更多相关文章
- Spring笔记07(Spring AOP的通知advice和顾问advisor)
1.Spring AOP的通知advice 01.接口代码: package cn.pb.dao; public interface UserDao { //主业务 String add(); //主 ...
- spring aop 环绕通知around和其他通知的区别
前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只 ...
- spring aop环绕通知
[Spring实战]—— 9 AOP环绕通知 假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Sprin ...
- Spring AOP前置通知和后置通知
Spring AOP AspectJ:Java社区里最完整最流行的AOP框架 在Spring2.0以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP 在Spring中启用Aspect ...
- Spring AOP高级——源码实现(2)Spring AOP中通知器(Advisor)与切面(Aspect)
本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/Spring%20AOP%E9%A ...
- [转载] spring aop 环绕通知around和其他通知的区别
前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只 ...
- Spring AOP前置通知实例说明AOP相关概念
今天又看了下韩顺平的SpringAOP的讲解,讲解的很透彻.仿照视频自己使用下前置通知. 一.引出问题 有个接口TestServiceInter,有两个实现方法TestService和Test2Ser ...
- Spring AOP前置通知实例讲解与AOP详细解析
一.引出问题 有个接口TestServiceInter,有两个实现方法TestService和Test2Service.他们都有sayHello():我们的需求是在调用这两个方法之前,要先完成写日志的 ...
- 【Spring AOP】通知(五)
一.通知介绍 1. 前置通知(Before) 在目标方法执行之前执行的通知. 前置通知方法,可以没有参数,也可以额外接收一个JoinPoint,Spring会自动将该对象传入,代表当前的连接点,通过该 ...
随机推荐
- Electro桌面应用开发之HelloWorld
简介 Electron (http://http://electron.atom.io)提供了一个使用Node.js进行桌面应用开发的环境. 本文介绍了一个基于Electron的HelloWorld ...
- C#串口通信—向串口发送数据,同步接收返回数据
最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...
- LINQ的Any方法
返回布尔值,判断集合中是否有元素满足某一条件. source code: IEnumerable<string> str = new List<string> { " ...
- Vimium 下载 像个 Geek 一样去浏览
插件地址(被墙):https://chrome.google.com/webstore/detail/dbepggeogbaibhgnhhndojpepiihcmeb 本地下载:http://file ...
- Kinect V2 基础教程之彩色图像
本程序为自己所写,参考素材包括微软官方例子和外文资料,自己做了部分的优化.解释的如果有问题,恳请大家指正. 后台代码: using System.ComponentModel; using Syste ...
- 背水一战 Windows 10 (4) - UI: 多窗口
[源码下载] 背水一战 Windows 10 (4) - UI: 多窗口 作者:webabcd 介绍背水一战 Windows 10 之 UI 多窗口 示例1.自定义帮助类,用于简化 Secondary ...
- 孙鑫MFC学习笔记6:菜单编程
1.对菜单响应的顺序: 视类,文档类,框架类,应用程序类 2.消息的分类 3.CWnd继承自CCmdTarget类, 所以从CWnd派生出的类也可以接收WM_COMMAND消息 4.命令的消息路由 5 ...
- SSH实例(4)
Clas.hbm.xml文件如下: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibe ...
- ActionContext和ServletActionContext区别
1. ActionContext 在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息, ...
- 说说这篇「我为什么从python转向go
作者 CMGS2015.05.17 15:47* 写了7891字,被143人关注,获得了97个喜欢 说说这篇「我为什么从python转向go」 字数3748 阅读24227 评论21 喜欢81 恩看了 ...