spring.net AOP初探
AOP是什么?
面向切面编程,在OO中有一个开放关闭原则,及对修改关闭,对扩展开放。AOP可以说是设计模式的集合加强版,使用代理、工厂、策略等等模式,来实现方法的结合。
这样说还比较模糊,我们先往下看。
AOP中常用的名词(这个先了解一下,最后再回来看就恍然大悟了):
Pointcut(切入点):被拦截到的点。如:在保存数据的方法中加入日志的方法,那么保存数据的方法就是切入点。
Advice(通知):指拦截之后所要做的事情就是通知。如上面例子,日志的方法就是通知。通知有4类,分别是前置通知,后置通知,异常通知,环绕通知。
Target(目标对象):代理的目标对象。如上面例子,保存数据方法的对象。
代理(proxy):由框架在将通知应用于目标对象后创建的对象。程序里通过GetProxy()方法创建出的代理对象。
spring.net中的AOP
spring.net是一个依赖注入框架,这里就用它在AOP方面的功能,初步谈一下他的实现方法,进入AOP的世界。
spring.net下载地址: http://www.springframework.net/
我们使用记日志的例子来实现一个简单的AOP:
创建一个控制台应用程序。
1、申明一个保存数据的接口
public interface IDataService { void SaveData(); }
2、实现一个保存数据的类
namespace AOPDmo.SaveData { public class DataService : IDataService { public void SaveData() { Console.WriteLine("保存数据..."); } } }
3、一个记日志的类
public class LogAdvice : IMethodInterceptor { private void Log() { Console.WriteLine("保存数据记日志"); } public object Invoke(IMethodInvocation invocation) { //Log(); object obj = invocation.Proceed(); Log(); //if (invocation.Method.Name == "") //用invocation.Method可以获取切入点的信息 //{ // Log(); //} return obj; } }
记日志的类作为一个和业务无关的通知,在需要的时候调用。这里继承spring的IMethodInterceptor(环绕通知)接口来告诉框架这是一个方法拦截器,并实现接口的Invoke方法,invocation.Proceed()方法使程序执行DataService类的SaveData()方法。
4、主页面,Program
class Program { static void Main(string[] args) { ProxyFactory factory = new ProxyFactory(new DataService()); factory.AddAdvice(new LogAdvice()); IDataService service = (IDataService)factory.GetProxy(); service.SaveData(); Console.Read(); } }
在Program中我们做了三件事情,
先告诉框架我们要对DataService做一个拦截器,用DataService作为目标对象,让框架创建一个代理工厂。
然后告诉代理工厂我们的通知是LogAdvice(可以添加多个)。
最后用代理工厂的方法factory.GetProxy()创建代理类。
执行结果:
到目前为止我们已经实现了一个简单的AOP记日志的功能,但是当我们不需要记日志了,那么就要删掉这里的代码,是不是感觉还不如直接写方法?
接下来我们用配置的方式来解决这个问题。
使用配置
创建一个xml文件
<?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="DataService" type="AOPDmo.DataService, AOPDmo"/> <object id="LogAdvice" type="AOPDmo.LogAdvice, AOPDmo"/> <object id="DataProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> <property name="ProxyInterfaces"> <list> <value>AOPDmo.IDataService,AOPDmo</value> </list> </property> <property name="Target"> <ref object="DataService" /> </property> <property name="InterceptorNames"> <list> <value>LogAdvice</value> </list> </property> </object> </objects>
头两个object是告诉框架创建代理类时所需的类名、所在程序集。
第三个object是需要创建的代理类,property是属性。
创建一个代理类同样需要做三件事:
1、属性Target(目标对象),先告诉框架我们要对DataService做一个拦截器,用DataService作为目标对象。
2、属性InterceptorNames(拦截器的名称),告诉代理工厂我们的通知是LogAdvice(可以添加多个)。
3、属性ProxyInterfaces是告诉框架代理类要继承的接口,创建代理类。
Program代码:
class Program { static void Main(string[] args) { IApplicationContext context = new XmlApplicationContext(@"XMLFile1.xml"); IDataService service = (IDataService)context.GetObject("DataProxy"); service.SaveData(); Console.Read(); } }
执行得到一样的结果,就不贴出来了。
当我们不需要日志的时候,将配置文件的<value>LogAdvice</value>代码注释掉就可以,是不是方便多了。
AOP的应用
我们在开发项目中,经常会遇到需要记录日志的地方,比如说机票系统中,机票做Update的时候,需要记录操作人是谁,什么时候修改的。比如监控我们系统中重要方法的执行,执行了多久,是否成功等等,主要应用在和业务无关,使用频率高的方法。
这篇主要是用ProxyFactory来创建AOP代理,后面的笔记将继续写一篇关于配置方面的内容,使AOP得到更灵活的应用。
最新文章
- mybatis源码分析:
- 2034-人见人爱A-B(c++实现)
- The C10K problem
- mysql安装过程中出现的错误问题解决方案
- hibernate的一对多、多对一详解
- js写分页
- 浅谈ThreadPool 线程池
- Android打开系统设置
- JS运算符、NaN
- java高并发实战(一)——为什么需要并发
- easyui 自定义验证规则 验证用户是否已经存在 远程ajax验证
- 【Python】如何基于Python写一个TCP反向连接后门
- Java 流(Stream)、文件(File)和IO -- Java ByteArrayInputStream类
- Vue.js 响应式原理
- Java面向对象技术
- linux ,cron定时任务 备份mysql数据库
- 最简单的rman操作
- 未注册在本地的Windows 2008 / Windows 7 X64的:&#39;Microsoft.Jet.OLEDB.4.0&#39;提供
- 用Tchromium替换webbrowser
- 【模板】string中substr函数的运用
热门文章
- [CLR via C#]1.5 本地代码生成器:NGen.exe
- (工具)source insight高速增加时间代码
- Linux环境编程相关的文章
- Hack 语言学习/参考---1.Hack 语言
- 加载xib文件的两种方式
- Effective C++ 10
- jQuery UI dialog 參数说明
- 多线程学习之二坚不可摧模式Immutable pattern
- Ninject.Extensions.
- Office 365 – Exchange Online examples