一、什么是AOP?
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
简单解释一下:
1.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
2.AOP可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
2.AOP可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
3 .借用
博客园-金源作者的两个图,一看就知道AOP做的是什么了
图一:
图二:
从图1、图2中我们就可以看出AOP的目的,就是将日志记录、验证、性能监测这些关注点从一个执行过程中分离了出来,让彼此不再有关系以及和计算总额的关系。在此可以把分离出来的关注点封装,已“面”的形式展现出来,这样的情况下也使得这些“面”可以在其它地方复用。原文请参考:
http://www.cnblogs.com/jin-yuan/p/3811077.html
二、基于.net实现AOP
先看看整个项目的结构:(后附带源码)
接下来我们一起来完成这个简单的项目:
说明:本例采用的一个计算器的例子,采用TransparentProxy和RealProxy实现对象的代理,实现思路: Client -TransparentProxy - RealProxy - Target Object.
通过这个实例,相信读者会对AOP有一个简单的认识。
1.新建一个Visual Studio 解决方案,命名为:AOPCaculatorPractice。
2.为新建的解决方案添加一个C#类库,命名为:NewAopCalculator。
3.为NewAopCalculator类库添加一个新类,定义一个类,名为Calculator,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NewAopCalculator
{
public class Calculator
{
private double _x;
private double _y;
public Calculator()
{ }
public Calculator(double x, double y)
{
this._x = x;
this._y = y;
}
public double X
{
get { return _x; }
set { _x = value; }
}
public double Y
{
get { return _y; }
set { _y = value; }
}
}
}
代码简单易懂,就不做解释了。
3.为NewAopCalculator类库添加一个新类,定义接口,名为ICalculaotr,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NewAopCalculator
{
public interface ICalculator
{
void Add(double x, double y);
void Substract(Calculator calcualtor);
}
}
4.
为NewAopCalculator类库添加一个新类,实现接口方法,名为RealizeCalculator,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NewAopCalculator
{
public class RealizeCalculator:MarshalByRefObject,ICalculator
{
public void Add(double x, double y)
{
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
}
public void Substract(Calculator calculator)
{
Console.WriteLine("{0} - {1} = {2}", calculator.X,calculator.Y,calculator.X - calculator.Y);
}
}
}
这里需要注意的是,必须要继承MarshalByRefObject,而且还要在接口之前继承.简单的说,如果你的某个类需要跨应用程序域边界甚至是远程访问的话,这个类可以继承marshalbyrefobject,例如你在使用remoting的时候,remoting代理的那个类,就必须要继承marshalbyrefobject.
5.准备工作做好了,接下来是重要的部分了。同样,我们需要
为NewAopCalculator类库添加一个新类,定义一个透明代理(TransparentProxy),,类名为:MyTransparentProxy,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
//TransparentProxy透明代理
namespace NewAopCalculator
{
public abstract class MyTransparentProxy
{
public static T Create<T>()
{
//创建真实实例
T instance = Activator.CreateInstance<T>();
//创建真实代理
MyRealProxy<T> realProxy = new MyRealProxy<T>(instance);
T transparentProxy = (T)realProxy.GetTransparentProxy();
//返回透明代理
return transparentProxy;
}
}
}
6.为为NewAopCalculator类库添加一个新类,定义一个真实代理(RealProxy),类名为:MyRealProxy,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
namespace NewAopCalculator
{
public class MyRealProxy<T>:RealProxy
{
private T _target;
public MyRealProxy(T target)
: base(typeof(T))
{
this._target = target;
}
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage callmessage = (IMethodCallMessage)msg;
//方法开始
PreProceede(callmessage);
//调用真实方法
object returnValue = callmessage.MethodBase.Invoke(this._target, callmessage.Args);
ReturnMessage message = new ReturnMessage(returnValue, new object[0], 0, null, callmessage);
//方法调用完成
PostProceede(message);
return message;
}
public void PreProceede(IMethodCallMessage msg)
{
//方法开始标识
Console.WriteLine("Start...");
//查看调用的方法传进来的参数
Console.WriteLine("Method:" + msg.MethodName.ToString());
for (int i = 0; i < msg.Args.Length; i++)
{
Console.WriteLine("{0}.The Args Is:{1}", i + 1, msg.Args[i]);
}
}
public void PostProceede(ReturnMessage msg)
{
//方法结束标识
Console.WriteLine("End\n");
}
}
}
其中, MyRealProxy<T> 是个泛型类型,泛型参数 T 是要拦截的对象的类型,MyRealProxy<T> 构造函数需要一个实现泛型参数的真实对象作为参数。
7.OK了,到了这里,基于透明代理(TransparentProxy)/真实代理(RealProxy)的实现方法拦截就告一段落了,接下来我们来用客户端调用,来看看客户端输出的是什么。为解决方法再添加一个控制台应用程序(ConsoleApplication)。命名为AOPCalculatorClient,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NewAopCalculator;
namespace AopCalculatorClient
{
class Program
{
static void Main(string[] args)
{
Calculator tor = new Calculator(12, 45);
RealizeCalculator calculator = MyTransparentProxy.Create<RealizeCalculator>();
calculator.Add(tor.X,tor.Y);
calculator.Substract(tor);
}
}
}
8.代码全部完结,设置AOPCalculatorClient为启动项目,我们来看看控制台输出结果吧。
很明显,实现了对方法的拦截过程。如果读者想很明确的知道是怎么调用的,可以自行进行单步调试,来加深理解。点击下载源码
本次博文到这里就结束了,由于小编也是初学AOP,有言语不准确之处,还望指出来,我们一起进步。