Spring.Net学习系列一(续):日志处理

本文接着上篇:Spring.Net学习系列一: 统一异常处理继续学习Spring.Net的AOP。

在这篇中,将利用前置通知(BeforeAdvice),通过.net的Attribute特性来实现日志处理。

在上一篇中,我们通过ProxyFactoryObject显式创建AOP代理的方法。如果应用程序需要创建很多AOP代理,比如当需要代理某个服务层或者数据访问层的所有对象时,这种方法就会使配置文件变的相当庞大。为简化配置过程,Spring.NET提供了“自动代理”的功能,可以根据条件自动创建代理对象,也就是说,可以将多个对象分组以作为要代理的候选对象。在本文中,将使用ObjectNameAutoProxyCreator进行自动代理。ObjectNameAutoProxyCreator可以用特定的文本值或通配符匹配目标对象的名称,并为满足条件的目标对象创建AOP代理。该类支持模式匹配字符串,如:"*name","name*",”*name*“和精确文本如"name"。

注:这里的ObjectName即为配置文件中objects节点下的一系列的object的名称

 

 首先创建前置通知的具体实现:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Aop;
using System.Web;

namespace Log
{
public class BeforeAdvice : IMethodBeforeAdvice
{
private Log logInstance;
public BeforeAdvice()
{
logInstance
= Log.GetInstance();
}
public void Before(System.Reflection.MethodInfo method, object [] args, object target)
{
Type dao
= target.GetType();
Object[] attributes
= dao.GetMethod(method.Name).GetCustomAttributes( true );
OperationAttribute attribute
= null ;
foreach ( object obj in attributes)
{
if (obj is OperationAttribute)
{
attribute
= obj as OperationAttribute;
break ;
}
}
if (attribute != null )
{
User user
= HttpContext.Current.Session[ " user " ] as User;
string strLogInfo = string .Format( " UserName:{0} ,OperationTime:{1},OperationType:{2},OperatedTarget:{3},Method:{4},Argument:{5} " ,
user.UserName, DateTime.Now, attribute.Op, target, method,ArrayToString(args));
logInstance.Info(strLogInfo);
}
}
private string ArrayToString( object [] args)
{
if (args == null || args.Length == 0 ) return " NULL " ;
string str = "" ;
foreach ( object o in args)
{
str
+= o.ToString() + " | " ; // 在实体类中,需要重写ToString方法,以获得更好效果
}
return str.TrimEnd( new char []{ ' | ' });
}
}
}

 

接下来模拟一个数据访问层IUserDao和实现类

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Collections.Generic;
using System.Text;

namespace Log
{
public interface IUserDao
{
IList
< User > GetUserByName( string userName, string password);

void SaveUser(User u);

void UpdateUser(User u);

void DeleteUser(User u);
}
}

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Log
{
public class UserDao:IUserDao
{
#region IUserDao 成员

[Operation(OperationEnum.Select)]
public IList < User > GetUserByName( string userName, string password)
{
return null ;
}

[Operation(OperationEnum.Insert)]
public void SaveUser(User u)
{
}

[Operation(OperationEnum.Update)]
public void UpdateUser(User u)
{
}

[Operation(OperationEnum.Delete)]
public void DeleteUser(User u)
{
}

#endregion
}
}

 

注意在UserDao实现类中已经加入了OperationAttribute。

OperationAttribute的代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Collections.Generic;
using System.Text;

namespace Log
{
[AttributeUsage(AttributeTargets.Class
| AttributeTargets.Method | AttributeTargets.Property, Inherited = true )]
public class OperationAttribute:Attribute
{
private OperationEnum op;
public OperationAttribute(OperationEnum op)
{
this .op = op;
}

public OperationEnum Op
{
get { return this .op; }
}
}
}

 

 

OperationEnum枚举类中定义了一些操作

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Collections.Generic;
using System.Text;

namespace Log
{
public enum OperationEnum
{
Select,
Insert,
Update,
Delete
}
}

 

 

接下来就是配置Spring的AOP了

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
<? 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 = " UserDao " type = " Log.UserDao, Log " />

<!-- Advice -->
< object id = " LogAdvice " type = " Log.BeforeAdvice, Log " />

< object id = " autoLogProxyCreator " type = " Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop " >
< property name = " ObjectNames " >
< list >
< value >* Dao </ value >
</ list >
</ property >
< property name = " InterceptorNames " >
< list >
< value > LogAdvice </ value >
</ list >
</ property >
</ object >
</ objects >

 

 

 

构建测试页面:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Spring.Context;
using Spring.Context.Support;
using Log;
public partial class _Default : System.Web.UI.Page
{
private IApplicationContext _ctx;
private IUserDao _userDao;
protected void Page_Load( object sender, EventArgs e)
{
User u
= new User();
u.UserName
= " huihui " ;
u.Password
= " HUIHUI " ;
Session[
" user " ] = u;
userDao.DeleteUser(u);
userDao.GetUserByName(u.UserName, u.Password);
}
private IApplicationContext ctx
{
get
{
if (_ctx == null )
{
_ctx
= ContextRegistry.GetContext();
}
return _ctx;
}
}

private IUserDao userDao
{
get
{
if (_userDao == null )
{
_userDao
= ctx[ " UserDao " ] as IUserDao;
}
return _userDao;
}
}


}

 

 

运行可以看到日志中已经记录如下内容:

2009-12-14 23:39:46,890 [4] INFO  AppLog [(null)] - UserName:huihui ,OperationTime:2009-12-14 23:39:46,OperationType:Delete,OperatedTarget:Log.UserDao,Method:Void DeleteUser(Log.User),Argument:Log.User
2009-12-14 23:39:46,921 [4] INFO  AppLog [(null)] - UserName:huihui ,OperationTime:2009-12-14 23:39:46,OperationType:Select,OperatedTarget:Log.UserDao,Method:System.Collections.Generic.IList`1[Log.User] GetUserByName(System.String, System.String),Argument:huihui|HUIHUI

 

日志输出格式可以根据项目需要自行调整,如果需要给管理员(针对用户)看日志,很明显上面的输出可能不太合适,这就需要对此进行一些调整。比如UserDao映射到“用户信息表”等等。

 

 

 

转载于:https://www.cnblogs.com/huihui-gohay/archive/2009/12/15/1624209.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值