一个用SpringAOP实现异常处理和记录程序执行时间的实例_第1页
一个用SpringAOP实现异常处理和记录程序执行时间的实例_第2页
一个用SpringAOP实现异常处理和记录程序执行时间的实例_第3页
一个用SpringAOP实现异常处理和记录程序执行时间的实例_第4页
一个用SpringAOP实现异常处理和记录程序执行时间的实例_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、5.11  一个用Spring AOP实现异常处理和记录程序执行时间的实例虽然前面也给出了Spring AOP的一些实例,但因为主要目的是为了介绍Spring的知识点,不一定会很完整,下面笔者就通过一个完整的用Spring AOP实现异常处理和记录程序执行时间的实例来展示使用Spring AOP的整个过程。5.11.1  异常处理和记录程序执行时间的实例简介这个实例主要用于在一个系统的所有方法执行过程中出现异常时,把异常信息都记录下来,另外记录每个方法的执行时间。用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动代理功能,然后一个用Java的动态

2、代理,一个用CGLIB代理。实现思路是:仍然使用前面所建的Java工程myApp,首先定义负责异常处理的Advice为ExceptionHandler.java,定义记录程序执行时间的Advice为TimeHandler.java,接着定义业务逻辑接口LogicInterface.java,编写实现业务逻辑接口的类Logic1.java,该业务逻辑在Spring AOP中使用Java的动态代理,编写另一个业务逻辑Logic2.java不实现业务逻辑接口,该业务逻辑在Spring AOP中使用CGLIB代理,然后使用自动代理定义配置文件config.xml,最后编写测试程序TestAop.jav

3、a,执行它并查看输出结果。下面就一步一步来实现这个实例。5.11.2  定义负责异常处理的Advice为ExceptionHandler.java在myApp工程的com.gc.action包中新建ExceptionHandler.java,该类主要负责当程序执行过程中出现异常时,把异常信息都记录下来。而Spring提供的通知类型中Throw通知可以实现这个功能,因此这里使用Throw通知类型来实现Advice,类ExceptionHandler必须实现ThrowsAdvice接口,重写afterThrowing()方法。ThrowsAdvice.java的示例代码如下:/* Exc

4、eptionHandler.java*package com.gc.action;import java.lang.reflect.Method;import org.apache.log4j.Level;import org.apache.log4j.Logger;import org.springframework.aop.ThrowsAdvice;/使用Throw通知类型来实现Advicepublic class ExceptionHandler implements ThrowsAdvice        

5、 private Logger logger = Logger.getLogger(this.getClass().getName();     /重写afterThrowing()方法    public void afterThrowing(Method method, Object args, Object target, Throwable subclass) throws Throwable            &

6、#160;       logger.log(Level.INFO, args0 + " 执行 " + method.getName() + " 时有异常抛出." + subclass);   代码说明:         必须重写afterThrowing()方法。         当程序有异常发生时,就会输出“

7、15;××执行×××方法时有异常抛出”和具体异常的记录信息。5.11.3  定义记录程序执行时间的Advice为TimeHandler.java在myApp工程的com.gc.action包中新建TimeHandler.java,该类主要负责记录每个方法的执行时间,而Spring提供的通知类型中Around通知可以实现这个功能,因此这里使用Around通知类型来实现Advice,类TimeHandler必须实现MethodInterceptor接口,重写invoke()方法。TimeHandler.java的示例代码如下:/* Tim

8、eHandler.java*package com.gc.action;import ercept.MethodInterceptor;import ercept.MethodInvocation;import org.apache.log4j.Level;import org.apache.log4j.Logger;/类TimeHandler必须实现MethodInterceptor接口public class TimeHandler implements MethodInterceptor  &

9、#160;      private Logger logger = Logger.getLogger(this.getClass().getName();     /重写invoke()方法    public Object invoke(MethodInvocation methodInvocation) throws Throwable             

10、       long procTime = System.currentTimeMillis();                   logger.log(Level.INFO, methodInvocation.getArguments()0 + " 开始执行 " + methodInvocation.getMethod() + &

11、quot; 方法");          try           Object result = methodIceed();           return result;            

12、     finally                             /计算执行时间procTime = System.currentTimeMillis() - procTime;        

13、                    logger.log(Level.INFO, methodInvocation.getArguments()0 + " 执行 " + methodInvocation.getMethod() + " 方法结束");          

14、60;                 logger.log(Level.INFO, "执行 " + methodInvocation.getMethod().getName() + " 方法共用了 " + procTime + "毫秒");           代码说明: &#

15、160;       必须重写invoke()方法。         当有方法执行时,就会输出“×××在什么时间开始执行×××方法”、“×××在什么时间执行×××方法结束”和“执行×××方法共用了×××毫秒”的记录信息。5.11.4  定义业务逻辑接口LogicInte

16、rface.java在myApp工程的com.gc.impl包中新建接口LogicInterface.java,该接口主要用来实现使用Spring AOP的动态代理机制,在这个接口里共定义了3个方法新增、修改和删除。LogicInterface.java的示例代码如下:/* LogicInterface.java*package com.gc.impl;/该接口主要用来实现使用Spring AOP的动态代理机制public interface LogicInterface          public void

17、doInsert(String name);         public void doUpdate(String name);         public void doDelete(String name);5.11.5  编写实现业务逻辑接口的类Logic1.java在myApp工程的com.gc.action包中新建业务逻辑类Logic1.java,该类主要负责具体的业务逻辑,这个类实现了前面定义的接口LogicI

18、nterface,并重写了接口LogicInterface定义的3个方法新增、修改和删除,用来实现使用Spring AOP的动态代理机制,并在删除方法里增加一个“i = i / 0”,用来模拟异常的发生。Logic1.java的示例代码如下:/* Logic1.java*package com.gc.action;import com.gc.impl.LogicInterface;/实现这个接口public class Logic1 implements LogicInterface         /负责新增&#

19、160;        public void doInsert(String name)                   System.out.println("执行具体负责新增的业务逻辑");           

20、;        for (int i = 0; i < 100000000; i+)                             /模拟执行时间        

21、                             /负责修改         public void doUpdate(String name)         

22、          System.out.println("执行具体负责修改的业务逻辑");                   for (int i = 0; i < 200000000; i+)         

23、0;                   /模拟执行时间                                

24、     /负责删除         public void doDelete(String name)                   System.out.println("执行具体负责删除的业务逻辑");     

25、60;             for (int i = 0; i < 300000000; i+)                             i = i / 0;/模拟异常发生 

26、                           5.11.6  编写一个不实现业务逻辑接口的类Logic2.java在myApp工程的com.gc.action包中新建业务逻辑类Logic2.java,该类主要负责具体的业务逻辑新增、修改和删除,这个类不实现前面定义的接口LogicInterface,用来实现使用Spring AOP

27、的CGLIB代理机制,并在删除方法里增加一个“i = i / 0”,用来模拟异常的发生。Logic2.java的示例代码如下:/* Logic2.java*package com.gc.action;/该类采用CGLIB代理机制public class Logic2          /负责新增         public void doInsert(String name)     

28、              System.out.println("执行具体负责新增的业务逻辑");                   for (int i = 0; i < 100000000; i+)     

29、0;                       /模拟执行时间                           

30、/负责修改         public void doUpdate(String name)                   System.out.println("执行具体负责修改的业务逻辑");         

31、0;         for (int i = 0; i < 200000000; i+)                             /模拟执行时间       

32、;                     /负责删除         public void doDelete(String name)                

33、   System.out.println("执行具体负责删除的业务逻辑");                   for (int i = 0; i < 300000000; i+)                

34、0;            i = i / 0;/模拟异常发生                            5.11.7  使用自动代理定义配置文件config.xml 在myApp根目录下,新建一个Sprin

35、g的配置文件exception_config.xml,主要用来使用Spring的自动代理功能,代理本系统所有的程序。exception_config.xml的示例代码如下:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-/SPRING/DTD BEAN/EN" ""><beans>  <bean id="logic1" class="com.gc.

36、action.Logic1"/>  <bean id="logic2" class="com.gc.action.Logic2"/>  <!-设定为自动代理->  <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>  <!-负责记录有异常发生时的信

37、息->  <bean id="exceptionHandler" class="com.gc.action.ExceptionHandler"/>    <bean id="exceptionHandlereAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">         <p

38、roperty name="advice">             <ref bean="exceptionHandler"/>         </property>                

39、;    <!-对指定类的任何方法有效->        <property name="patterns">             <value>.*.*</value>         </property>   </

40、bean>   <!-负责记录方法的记录时间->  <bean id="timeHandler" class="com.gc.action.TimeHandler"/>  <bean id="timeHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">       

41、60; <property name="advice">             <ref bean="timeHandler"/>         </property>              &#

42、160;    <!-对指定类的任何方法有效->        <property name="patterns">             <value>.*.*</value>         </property>  

43、60;  </bean> </beans>5.11.8  编写测试类Logic1的程序TestAop.java在myApp工程的com.gc.test包中新建测试类TestAop.java,该类主要负责对前面程序的测试和演示,这里先编写对业务逻辑Logic1.java的演示。TestAop.java的示例代码如下:/* TestAop.java*package com.gc.test;import org.springframework.context.ApplicationContext;import org.springframework.con

44、text.support.;import com.gc.impl.LogicInterface;public class TestAop          public static void main(String args) throws InstantiationException, IllegalAccessException, ClassNotFoundException            &

45、#160;       /通过ApplicationContext获取配置文档                   ApplicationContext actx=new ("exception_config.xml");          

46、;         LogicInterface logic = (LogicInterface)actx.getBean("logic1");                   /模拟执行新增、修改、删除方法         

47、          try                             logic.doInsert("张三");        

48、;                    logic.doUpdate("李四");                         

49、60;  logic.doDelete("王五");                   catch (Exception ex)                       &#

50、160;     5.11.9  输出自动代理时类Logic1异常处理和记录程序执行时间的信息运行测试程序,即可看到记录Logic1.java中每个方法执行时间和在删除方法里捕获的异常的信息,如图5.16所示。图5.16  记录Logic1.java中每个方法执行时间和在删除方法里捕获的异常信息5.11.10  编写测试类Logic2的程序TestAop.java上面主要是针对业务逻辑Logic1.java的测试,所以在记录的信息中,类名显示的是Logic1实现的接口LogicInterface的名称,对于业务逻辑Logic

51、2.java的测试,需要修改测试代码TestAop.java。TestAop.java的示例代码如下:/* TestAop.java*package com.gc.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.;import com.gc.action.Logic2;public class TestAop          public static voi

52、d main(String args) throws InstantiationException, IllegalAccessException, ClassNotFoundException /通过ApplicationContext获取配置文档                   ApplicationContext actx=new ("exception_config.xml");

53、60;                  Logic2 logic2 = (Logic2)actx.getBean("logic2");                   /模拟执行新增、修改和删除方法  &

54、#160;                try                             logic2.doInsert("张三"); 

55、;                           logic2.doUpdate("李四");                  &#

56、160;         logic2.doDelete("王五");                   catch (Exception ex)               &

57、#160;                                         5.11.11  输出自动代理时类Logic2异常处理和记录程序执行时间的信息运行测试程序,即可看到记录Logic2.

58、java中每个方法执行时间和在删除方法里捕获的异常的信息,如图5.17所示。图5.17  记录Logic2.java中每个方法执行时间和在删除方法里捕获的异常信息上面主要是针对业务逻辑Logic2.java的测试,所以在记录的信息中,类名显示的是Logic2的名称。这是使用接口和不使用接口时显示信息的主要区别。以上示例使用的是Spring AOP的自动代理,那对于使用Spring AOP的动态代理和CGLIB代理来说,应该怎么实现呢?下面就来讲解使用ProxyFactoryBean实现动态代理和CGLIB代理。5.11.12  使用ProxyFactoryBean代理定义配

59、置文件config.xml改写Spring的配置文件exception_config.xml,主要用来使用Spring的ProxyFactoryBean代理功能,对Logic1.java只记录程序执行时间,不捕获发生的异常,对Logic2.java只捕获发生的异常,不记录程序执行时间,去掉前面的自动代理。exception_config.xml的示例代码如下:<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-/SPRING/DTD BEAN/EN&qu

60、ot; ""><beans>  <bean id="logic1" class="com.gc.action.Logic1"/>  <bean id="logic2" class="com.gc.action.Logic2"/>  <!-设定为自动代理->  <!-负责记录有异常发生时的信息->  <bean id="exceptionHandler&qu

61、ot; class="com.gc.action.ExceptionHandler"/>    <bean id="exceptionHandlereAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">         <property name="advice">   &#

62、160;         <ref bean="exceptionHandler"/>         </property> <!-对指定类的任何方法有效->        <property name="patterns">      &

63、#160;      <value>.*.*</value>         </property>   </bean>   <!-负责记录方法的记录时间->  <bean id="timeHandler" class="com.gc.action.TimeHandler"/>  <bean id="timeH

64、andlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">         <property name="advice">             <ref bean="timeHandler"/>  

65、;       </property>         <!-对指定类的任何方法有效->        <property name="patterns">             <value>.*.*</valu

66、e>         </property> </bean><bean id="logic1Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">         <property name="proxyInterfaces">    

67、         <value>com.gc.impl.LogicInterface</value>        </property>        <property name="target">         &

68、#160;  <ref bean="logic1"/>        </property><!-指定代理类->        <property name="interceptorNames">            <list>

69、0;               <value>timeHandlerAdvisor</value>            </list>        </property>    </bean

70、>    <bean id="logic2Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">         <property name="proxyTargetClass">             <val

71、ue>true</value>        </property>        <property name="target">            <ref bean="logic2"/>     

72、   </property><!-指定代理类->        <property name="interceptorNames">            <list>             

73、0;  <value>exceptionHandler</value>            </list>        </property>    </bean></beans>5.11.13  编写测试类Logic1的程序TestAop.java这里先改写对业务逻辑Logic1.java的

74、演示。TestAop.java的示例代码如下:/* TestAop.java*package com.gc.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.;import com.gc.impl.LogicInterface;public class TestAop          public static void main(String args) th

75、rows InstantiationException, IllegalAccessException, ClassNotFoundException /通过ApplicationContext获取配置文档                   ApplicationContext actx=new ("exception_config.xml");    &

76、#160;              LogicInterface logic = (LogicInterface)actx.getBean("logic1Proxy");/模拟执行新增、修改和删除方法                   try   

77、;                          logic.doInsert("张三");                     

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论