Spring. Net Learning Series 1: Unified Exception Handling

Source: Internet
Author: User
Tags log4net

In actual projects, log processing is a common function. How to handle exceptions in a unified manner?
The general practice is to write a LogProvider class or ILogProvider interface, and then write the error information to a file or database through this provider.
For example:
Try
{
HelloWorld. Show ();
}
Catch (Exception ex)
{
LogProvider. Write (ex. StackTrace );
MessageBox. show ("error occurred ");
}
 
 
LogProvider. Write (ex. StackTrace) is everywhere );
Does such similar code smell bad?
Yes, we need to find a way to put it in a unified place. First, the code is beautiful, and second, it is easy to maintain.
At this time, Spring.net was launched. Using Spring AOP and proxy, we can easily and uniformly handle the exception information.
Of course, exception records are generally handled through the Log Module. Therefore, we first implement a Log Module. Here we use the well-known Log4Net,
The Code is as follows:
 
 
Code
1 using System;
2 using System. Collections. Generic;
3 using System. Text;
4
5 namespace Log
6 {
7. public class Log
8 {
9 private static Log instance;
10 private static readonly log4net. ILog log = log4net. LogManager. GetLogger ("AppLog ");
11 private static object obj = new object ();
12 private Log ()
13 {
14
15}
16 /// <summary>
17 // obtain the Log Singleton
18 /// </summary>
19 /// <returns> </returns>
20 public static Log GetInstance ()
21 {
22 if (instance = null)
23 {
24 lock (obj)
25 {
26 instance = new Log ();
27 log4net. Config. XmlConfigurator. Configure ();
28}
29}
30 return instance;
31}
32
33 public void Debug (object o)
34 {
35 if (log. IsDebugEnabled)
36 {
37 if (o is Exception) log. Debug ("Debug", o as Exception );
38 else log. Debug (o. ToString ());
39
40}
41}
42
43 public void Error (object o)
44 {
45 if (log. IsErrorEnabled)
46 {
47 if (o is Exception) log. Error ("Error", o as Exception );
48 else log. Error (o. ToString ());
49}
50}
51
52 public void Warn (object o)
53 {
54 if (log. IsWarnEnabled)
55 {
56 if (o is Exception) log. Warn ("Warn", o as Exception );
57 else log. Warn (o. ToString ());
58}
59}
60
61 public void Info (object o)
62 {
63 if (log. IsInfoEnabled)
64 {
65 if (o is Exception) log. Info ("Info", o as Exception );
66 else log. Info (o. ToString ());
67}
68}
69
70 public void Fatal (object o)
71 {
72 if (log. IsFatalEnabled)
73 {
74 if (o is Exception) log. Fatal ("Fatal", o as Exception );
75 else log. Fatal (o. ToString ());
76}
77}
78}
79}
80
 
Next we will use Spring. net's AOP feature implements unified Exception Handling. If we need to perform some operations when exceptions occur, we must implement Spring. aop. IThrowsAdvice, which does not have any implementation method, is an empty interface, it only exists as a tag interface, but the class that implements the IThrowsAdvice interface must define at least one AfterThrowing method, the method signature is as follows:
AfterThrowing ([MethodInfo method, Object [] args, Object target], Exception subclass );
The first three parameters enclosed in brackets are optional, and the return value can be of any data type. Spring. aop. framework. adapter. the ThrowsAdviceInterceptor class implements Spring. aop. method dependency injection in the IThrowsAdvice derived class. The ThrowsAdviceInterceptor () method checks Spring. aop. whether the derived class of IThrowsAdvice defines at least one exception handling method. If not, an ArgumentException exception is thrown. MapAllExceptionHandlingMethods () methods are used to find out the closest method between the exception type and the type defined by the last parameter in the defined overload method, and we should not implement two methods with the same exception type in them, even if their parameter numbers are different, an ArgumentException exception is thrown.
 
Code
1 using System;
2 using System. Collections. Generic;
3 using System. Text;
4 using Spring. Aop;
5 using System. Reflection;
6 namespace Log
7 {
8 public class ExceptionThrowAdvice: IThrowsAdvice
9 {
10 private Log logInstance;
11
12 public ExceptionThrowAdvice ()
13 {
14 logInstance = Log. GetInstance ();
15}
16
17 public void AfterThrowing (MethodInfo method, Object [] args, Object target, Exception exception)
18 {
19 logInstance. Error (exception );
20}
21}
22}
23
 
Next, let's test the effect.
First, define an interface and implementation class.
If spring.net + nhibice is used, here is the Service and IService (you are familiar with it)
Using System;
Using System. Collections. Generic;
Using System. Text;

Namespace LogTest
{
Public interface IHelloWorld
{
Void Show ();
}
}
 
 
Code
Using System;
Using System. Collections. Generic;
Using System. Text;

Namespace LogTest
{
Public class HelloWorld: IHelloWorld
{
# Region IHelloWorld Member

Public void Show ()
{
Throw new Exception ("Exception occurred ");
}

# Endregion
}
}
 
Then there is the configuration file.
Objects. xml
Code
<? 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 = "ExceptionThrowAdvice" type = "Log. ExceptionThrowAdvice, Log"/>
<Object id = "HelloWorld" type = "LogTest. HelloWorld, LogTest"/>

<Object id = "HelloWorldProxy" type = "Spring. Aop. Framework. ProxyFactoryObject, Spring. Aop">
<Property name = "ProxyInterfaces">
<List>
<Value> LogTest. IHelloWorld, LogTest </value>
</List>
</Property>
<Property name = "Target">
<Ref object = "HelloWorld"/>
</Property>
<Property name = "InterceptorNames">
<List>
<Value> ExceptionThrowAdvice </value>
</List>
</Property>
</Object>

</Objects>
 
App. config
 
Code
<? Xml version = "1.0" encoding = "UTF-8"?>
<Configuration>
<ConfigSections>
<SectionGroup name = "spring">
<Section name = "context" type = "Spring. Context. Support. ContextHandler, Spring. Core"/>
<Section name = "objects" type = "Spring. Context. Support. DefaultSectionHandler, Spring. Core"/>
</SectionGroup>
<Section name = "log4net" type = "log4net. Config. Log4NetConfigurationSectionHandler, log4net"/>
</ConfigSections>

<! -- Spring configuration -->
<Spring>
<Context>
<Resource uri = "~ /Objects. xml "/>
</Context>
</Spring>

<! -- Log output definition -->
<Log4net>
<Appender name = "LogFileAppender" type = "log4net. Appender. FileAppender">
<Param name = "File" value = "log. text"/>
<Param name = "datePattern" value = "MM-dd HH: mm"/>
<Param name = "AppendToFile" value = "true"/>
<Layout type = "log4net. Layout. PatternLayout">
<Param name = "ConversionPattern" value = "% d [% t] %-5 p % c [% x]-% m % n"/>
</Layout>
</Appender>
<Appender name = "AppLogAppender" type = "log4net. Appender. FileAppender">
<Param name = "File" value = "AppLog. text"/>
<Param name = "datePattern" value = "MM-dd HH: mm"/>
<Param name = "AppendToFile" value = "true"/>
<Layout type = "log4net. Layout. PatternLayout">
<Param name = "ConversionPattern" value = "% d [% t] %-5 p % c [% x]-% m % n"/>
</Layout>
</Appender>
<Logger name = "Spring">
<Level value = "INFO"/>
<Appender-ref = "LogFileAppender"/>
</Logger>
<Logger name = "nhib.pdf">
<Level value = "INFO"/>
<Appender-ref = "LogFileAppender"/>
</Logger>
<Logger name = "AppLog">
<Level value = "ALL"/>
<Appender-ref = "AppLogAppender"/>
</Logger>
</Log4net>
</Configuration>
 
 
Then in our Startup Program
 
Code
Using System;
Using System. Collections. Generic;
Using System. ComponentModel;
Using System. Data;
Using System. Drawing;
Using System. Linq;
Using System. Text;
Using System. Windows. Forms;
Using Spring. Context;
Using Spring. Context. Support;
Using Log;

Namespace LogTest
{
Public partial class Form1: Form
{
Private IApplicationContext _ ctx;
Private IHelloWorld _ helloWorld;
Public Form1 ()
{
InitializeComponent ();
Try
{
HelloWorld. Show ();
}
Catch
{
MessageBox. Show ("exception occurred ");
}
}
Private IApplicationContext ctx
{
Get
{
If (_ ctx = null)
{
_ Ctx = ContextRegistry. GetContext ();
}
Return _ ctx;
}
}
Private IHelloWorld helloWorld
{
Get
{
If (_ helloWorld = null)
{
_ HelloWorld = ctx ["HelloWorldProxy"] as IHelloWorld;
}
Return _ helloWorld;
}
}
}
}
 
 
. Okay, you can see that the Code is the same when the Code does not record the exception information, but the exception statistical record is implemented. You can see that the error information has been written in the log file.
Click to download the sample source code
 
 
[Reference from Spring Technical Manual below]
Note that when an exception occurs, the Throw Advice task only executes the corresponding method. You cannot handle the exception in Throw Advice. After Throw Advice is executed, the plaintiff's exception will still be transmitted to the application. Throw Advice is not involved in the exception handling of the application, and the exception handling is still the responsibility of the application itself, if you want to abort the application processing process during Throw Advice processing, you can Throw other exceptions.
 
 
 
 
The running effect text is described as follows:
An exception occurred in the pop-up dialog box"
Record the error information in the AppLog. text file:
16:34:17, 812 [11] ERROR AppLog [(null)]-Error
System. Exception: An Exception occurs.
In the LogTest. HelloWorld. Show () Location F: \ Study \ LogAop \ LogTest \ HelloWorld. cs: Row 13
In _ dynamic_LogTest.HelloWorld.Show (Object, Object [])
In Spring. Reflection. Dynamic. SafeMethod. Invoke (Object target, Object [] arguments)
In Spring. Aop. Framework. DynamicMethodInvocation. InvokeJoinpoint ()
In Spring. Aop. Framework. AbstractMethodInvocation. Proceed ()
In Spring. Aop. Framework. Adapter. ThrowsAdviceInterceptor. Invoke (IMethodInvocation invocation)

Author: "Computer Encyclopedia (only used for technology .."

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.