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会自动将该对象传入,代表当前的连接点,通过该 ...
随机推荐
- Azure REST API (1) 前言
<Windows Azure Platform 系列文章目录> 一.服务运行时API简介 微软的Windows Azure服务总线提供了一整套REST风格的API,其中包括服务运行时API ...
- 【手把手教你全文检索】Lucene索引的【增、删、改、查】
前言 搞检索的,应该多少都会了解Lucene一些,它开源而且简单上手,官方API足够编写些小DEMO.并且根据倒排索引,实现快速检索.本文就简单的实现增量添加索引,删除索引,通过关键字查询,以及更新索 ...
- JVM之类加载器下篇
除了自定义的类加载之外,jvm存在三种类加载器,并以一种父委托的加载机制进行加载. --启动类加载器,又称根加载器,是一个native的方法,使用c++实现.在java中我们用null标识,用于加载j ...
- 初探Spring - IOC原理
一.IOC是什么 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来降低代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency ...
- 【转载】Lucene.Net入门教程及示例
本人看到这篇非常不错的Lucene.Net入门基础教程,就转载分享一下给大家来学习,希望大家在工作实践中可以用到. 一.简单的例子 //索引Private void Index(){ Index ...
- C#执行存储过程的简化
下面的方法是我在实际开发中摸索出来的,可以在很大程度上简化调用存储过程的代码. 首先来看一下C#调用存储过程的一般过程:1.打开数据库连接SqlConnection:2.生成一个SqlCommand: ...
- 【iOS】配置和使用静态库
上一篇 我们演示了了如何创建自己的静态库,最终生成多个.a文件,根据需要引用工程就可以直接使用静态库了,但是有个很麻烦的问题,模拟器用的库和真机的不是同一个,当我们切换的时候需要更换静态库,有两种方式 ...
- WinPhone学习笔记(三)——WinPhone的动画
这段时间又一直赶任务,结果没有去学习,也没有去写博文,这个动画的内容很早就学了,但是一直没把它整理成博文,现在终于有空就弄一下. 开始先讲讲在WinPhone中做动画有两种动画类型,一种是基于帧动画另 ...
- 微信--获取jsapi_ticket 然后在计算出signature
最近做微信公众号,记录一下,仅供参看. 关于jsapi_ticket微信公众号有相关说明: 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临 ...
- Oracle数据库,非空约束、主键约束、外键约束、唯一约束
非空约束:设置列时,可为空默认可为空,去掉对号之后设置数据不可为空: 唯一约束:在键中设置,唯一约束名称.类型Unique.列名:设置应用完成之后,此列数据具有唯一性:即数据不可重复(类型:Uniqu ...