通常我们对于异常的处理方式都是大同小异的,要么直接捕获并处理,要么让它抛向上一层,要么就是记录到日志里,或者发邮件提供管理员,但这样下来一个项目中便会到处充斥着 try/catch ,并且 catch 中的代码基本类似,于是我们闻到的其中难闻的坏味道。
本文将介绍如何通过 Spring.Net 的 AOP 特性实现异常的统一处理,如果我们需要在异常发生时做一些操作的话我们就必须实现 Spring.Aop.IThrowsAdvice,该接口没有任何实现方法,是一个空接口,它仅仅做为一个标记接口而存在,但实现了 IThrowsAdvice 接口的类必须定义至少一个 AfterThrowing 方法,方法的签名如下:
AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass);
其中中括号括起来的前三个参数是可选的,返回值可以是任意数据类型。Spring.Aop.Framework.Adapter.ThrowsAdviceInterceptor 类实现对实现了 Spring.Aop.IThrowsAdvice 派生类中的方法依赖注入,其中的 ThrowsAdviceInterceptor() 方法检查 Spring.Aop.IThrowsAdvice 的派生类是否定义了至少一个异常处理方法,如果没有则抛出 ArgumentException 异常,MapAllExceptionHandlingMethods() 方法则在定义好的重载方法中查找出异常类型与最后一个参数所定义的类型中最接近的方法,而且我们不应该在其中实现了两个相同异常类型的方法,即使他们的参数数目不同,否则也将抛出 ArgumentException 异常。
[下面引用自《Spring 技术手册》第4章 P94 页中的一段话]
注意到当异常发生时, Throw Advice 的任务只是执行对应的方法,您并不能在 Throw Advice 中将异常处理掉,在 Throw Advice 执行完毕后,原告的异常仍将传播至应用程序之中, Throw Advice 并不介入应用程序的异常处理,异常处理仍旧是应用程序本身所要负责的,如果想要在 Throw Advice 处理时中止应用程序的处理流程,作法是抛出其它的异常。
接下来看个 Throws Advice 的实际例子,首先定义 IHello 接口:
|
接着定义一个 HelloSpeaker 类来实现 IHello 接口,并在 Hello() 方法中模拟程序发生错误时的异常抛出:
|
如果您需要在应用程序抛出异常时,介入 Throw Advice 提供一些服务,例如记录一些异常信息,则可以实现 Spring.Aop.IThrowsAdvice 接口,在这个例子中我使用了 log4net 组件来实现日志的记录:
|
接着在配置文件(我这里使用了独立配置文件)中写下以下的定义,让 Throw Advice 在异常发生时提供记录服务:
xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net
http://www.springframework.net/xsd/spring-objects.xsd">
<object id="SomeThrowAdvice" type="TestThrowAdvice.SomeThrowAdvice,
TestThrowAdvice" />
<object id="HelloSpeaker" type="TestThrowAdvice.HelloSpeaker,
TestThrowAdvice" />
<object id="HelloProxy" type="Spring.Aop.Framework.ProxyFactoryObject,
Spring.Aop" >
<property name="ProxyInterfaces">
<list>
<value>TestThrowAdvice.IHello,TestThrowAdvice< SPAN>value>
< SPAN>list>
< SPAN>property>
<property name="Target">
<ref object="HelloSpeaker" />
< SPAN>property>
<property name="InterceptorNames">
<list>
<value>SomeThrowAdvice< SPAN>value>
< SPAN>list>
< SPAN>property>
< SPAN>object>
< SPAN>objects>
最后剩下我们的程序入口 Main() 函数了:
|
程序执行结果输出:
Hello, Justin
发生异常...
日志记录中的结果:
2006-10-30 20:59:03,125 [4020] INFO TestThrowAdvice.SomeThrowAdvice - 记录异常
System.Exception: 发生异常...
在 TestThrowAdvice.HelloSpeaker.Hello(String name) 位置 E:\..\..\SpringNetDemo\TestThrowAdvice\HelloSpeaker.cs:行号 14
在 Spring.Objects.ObjectUtils.InvokeMethod(MethodInfo method, Object instance, Object[] arguments) 位置 c:\projects\daily\Spring.Net\src\Spring\Spring.Core\Objects\ObjectUtils.cs:行号 489
在 Spring.Aop.Framework.ReflectiveMethodInvocation.InvokeJoinpoint() 。。。。。
|
||||
| · 技术人求职简历完备手册 · 华为员工自杀频频拷问.. · 视频访谈:网管员如何踏.. · 首届中国IT工程师生态.. · 思科全球CEO钱伯斯第七.. · 北漂技术人90天求职纪实 · 2007年互联网大会 · 龙芯要做中国的“奔腾” |
· IPv6协议--拓展网络无.. · 国际文档格式标准开战 · 微软出价446亿美元收购.. · 贝恩资本携手华为22亿.. · Linux——从菜鸟到高手 · SOA 面向服务架构 · 2008年4月全国计算机等.. · 微软Forefront企业安全.. |
|||
|
||||
| · SQL Server 2008/2005.. · SOA 面向服务架构 · SQL Server 2008/2005.. · iSCSI应用与发展 · RAID——磁盘阵列基础 · 中间件应用技术专题 · SQL Server入门到精通 · 病毒查杀专题 |
· 国际文档格式标准开战 · 路由器设置与口令恢复 · Linux防火墙 · 打造安全服务器 · SOA 面向服务架构 · PHP开发应用手册 · ADSL应用面面俱到 · 入侵防护系统(IPS)初探 |
|||
|
||||
| · iSCSI应用与发展 · 中间件应用技术专题 · SQL Server入门到精通 · SQL Server 2008/2005.. · SOA 面向服务架构 · iSCSI应用与发展 · RAID——磁盘阵列基础 · 病毒查杀专题 |
· 路由器设置与口令恢复 · SOA 面向服务架构 · 了解统一威胁管理(UTM).. · ADSL应用面面俱到 · ADSL应用面面俱到 · PHP开发应用手册 · 中间件应用技术专题 · Linux防火墙 |
|||