Spring学习心得(18)-- 通知的种类
来源:互联网 发布:unity3d ios 交互 编辑:程序博客网 时间:2024/05/21 17:32
通知的种类:
1、前置通知2、后置通知3、最终通知4、异常通知5、环绕通知
在之前的例子中,我们使用到了before(前置通知)和after-returning(后置通知)。还有after最终通知(最终通知)和around(环绕通知)。
前置通知和后置通知已经在前面的帖子涉及到,这里只做总结:
前置通知:
*在目标方法执行前执行*所以目标方法如果出现异常,这里还会执行
后置通知:
*在目标方法执行后执行*如果目标方法出现异常,这里不会执行*可以接收由目标方法的返回值
配置如下:
*注意:这些配置是在标签里面定义的
<!-- aop配置 --> <aop:config> <!-- aop:pointcut 指的是切入点判断,我们昨天使用的是在拦截器中使用if方法,具体内容可以看上一篇帖子 但是考虑到如果有很多个dao,那么就要判断很多次,效率会降低 expression 指的是切入点的表达式,该表达式的作用就是调用哪些方法, 一般都使用简写形式,即只需标明 (* *(..)), 第一个*是指返回值类型,第二个是指方法全名 括号中的.. 类似于可变参数的作用, 在这里我们执行的是目标类PersonDaoImpl 的某个方法 id 是指对这个切入点的唯一标识符 --> <aop:pointcut expression="execution(* cn.ansel.aopExample.PersonDaoImpl.*(..))" id="perform"/> <!-- aop:aspect 定义切面,因为要把相应的类定义到配置文件中才算是切面 id 该切面的唯一标识符 ref 该切面的引用对象 --> <aop:aspect id="mytransaction" ref="myTransaction"> <!-- method 指对应切面中的通知,这里的method对应的切面,就是上级标签ref对应的切面 pointcut-ref 指该值对应的切入点表达式 before 指前置通知的配置 --> <aop:before method="before" pointcut-ref="perform" /> <!-- aop:after-returning 指后置通知的定义标签 returning 指目标方法中返回值的名称 --> <aop:after-returning method="afterReturning" pointcut-ref="perform" returning="var"/> </aop:aspect> </aop:config>
/目标类的代码:public class PersonDaoImpl extends hibernateUtil { public String savePerson(Person person) { System.out.println("targetMethod"); //返回字符串 return "the object form targetMethod"; }}//切面中方法:public class MyTransaction extends hibernateUtil{ public void before(){ System.out.println("beforeMethod"); } public void afterReturning(Object var){ //接收目标类返回值,并输出 System.out.println(var); }}//测试类的方法:public class testAOP { @Test public void test(){ //加载spring配置文件 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("cn/ansel/aopExample/applicationContext.xml"); //得到目标类 PersonDaoImpl dao=(PersonDaoImpl) applicationContext.getBean("personDaoImpl"); //存入数据 Person person=new Person(); person.setPname("ansel"); person.setPdescription("fine"); dao.savePerson(person); }}
运行结果:
*主要注意的是:在配置文件中配置的returning参数的名字,必须与切面的后置通知中的传入参数的名字要一致,否则会报错
example:
//我把后置通知中的传入参数名字改成sth,然后再输出sth public void afterReturning(Object sth){ //接收目标类返回值,并输出 System.out.println(sth); }
此时,目标方法不变,继续执行测试类的运行结果,有一大堆报错,于是我标注了重要的提示:
最终通知:
直接看配置:在切面中,直接写一个新的方法作为最终通知,然后在配置文件中配置
//最终通知 public void after(){ System.out.println("after"); }<!-- 配置文件中的配置,在刚刚后置通知的后面加上这一行代码 after 指最终通知,其他没有什么不同,需要注意的是,配置每一个通知的时候,都不要忘记了pointcut-ref的引用--><aop:after method="after" pointcut-ref="perform" />
目标方法不变,运行结果:
要看最终通知有什么真正的效果,由于最终的名字,想到了Java中有一个finally代码块,所以我们在目标方法加一个异常:
public class PersonDaoImpl extends hibernateUtil { public String savePerson(Person person) { //添加一个异常,用来测试最终通知的作用 int a=1/0; System.out.println("targetMethod"); //返回字符串 return "the object form targetMethod"; }}
运行结果:毫无意外的报了异常,可是最终通知运行了,后置通知没有运行,目标方法也没有运行
由此可以看出,最终通知跟finally代码块的作用是一致的,finally也是最终的意思好吧。。
异常通知:
该通知的作用主要用于返回目标方法中出现的异常。配置如下:
在切面中增加这样一个方法:
/** * 异常通知 * @param ex 参数为目标方法中返回的异常,改名字与配置文件中的throwing配置的名字要一致 * 否则跟上面返回值一样报错 */ public void throwing(Throwable ex){ System.out.println(ex.getMessage()); }
<!-- 配置文件: aop:after-throwing 指异常通知,接收目标方法发生的异常 throwing 指目标方法抛出异常的引用名--> <aop:after-throwing method="throwing" pointcut-ref="perform" throwing="ex"/>
测试类不变,运行结果为:
环绕通知:
用来控制目标方法是否执行。
//ProceedingJoinPoint 该类有一个proceed方法,用来控制目标方法是否执行。 在这里我们先不用那个方法,看看目标方法是否会执行public void around(ProceedingJoinPoint joinPoint){ System.out.println("around"); }配置文件:
<!-- aop:around 配置环绕通知 --> <aop:around method="around" pointcut-ref="perform"/>
运行结果:
在目标方法中有
- 1
- 1
但是没有报错,并且只是执行了前置通知和环绕通知。这时候最终通知也不执行了。
但是当我调用ProceedingJoinPoint类的proceed方法时,这里先把异常代码注释掉:
目标类代码:
public class PersonDaoImpl extends hibernateUtil { public String savePerson(Person person) { //添加一个异常,用来测试最终通知的作用// int a=1/0; System.out.println("targetMethod"); //返回字符串 return "the object form targetMethod"; }}环绕通知的代码该为:
public void around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("around"); //调用proceed方法 joinPoint.proceed(); }
运行结果为:
全部配置的通知都执行了,除了异常通知。
0 0
- Spring学习心得(18)-- 通知的种类
- 6、spring的五种类型通知
- 我的Spring之旅——(三)AOP通知的几种类型
- 通知的种类
- Spring---AOP基本概念以及Advice5种类型的通知注解应用实例
- spring事务管理的种类
- spring事务管理的种类
- spring的bean种类
- Spring学习心得(3)-- Spring容器创建对象的时机
- Spring学习心得(5)-- spring容器创建对象的生命周期
- Spring学习心得(21)-- spring与jdbc结合的方式
- spring 事务属性的种类
- Spring 事务属性的种类
- Spring框架------Bean的种类
- 5.5 Spring的通知(Advice)
- spring 的环绕通知
- spring的各种通知
- spring的通知(advice)
- HTTP协议/IIS 原理及ASP.NET运行机制浅析
- 常用的sql查询
- ACM刷题之Hdu ————How Many Tables
- WebDriver介绍
- 动态规划(篇3)最长公共子序列(LCS)
- Spring学习心得(18)-- 通知的种类
- 第一、Java的开发前奏
- cuda8+cuDNN Faster R-CNN安装塈运行demo
- 《百度URL采集器》
- 射频识别技术漫谈(10)——识别号的格式变化
- MyBatis之动态SQL
- 条款06:若不想使用编译器自动生成的函数,就该明确拒绝
- 35. Search Insert Position
- 学习记录