标签:aop
AOP的意思是面向方面编程,英文全称是Aspect Oriented Programming,它的作用是讲彼此先和在一起的功能分离开,简单来说就是解耦和。
我们编写应用程序时,通常包含两种代码:一种是和业务系统有关的代码,一是和业务系统关系不大的代码,例如日志、权限、异常处理、事务处理等。以前编写代码时,这两种代码基本是写在一起的,这样在程序中,到处充满着相同或类似的代码,例如日志信息的输出,每个方法都要写日志的输出,不利于程序的维护。而AOP就是使这两种代码分离的思想。使用AOP,就不用在业务逻辑中实现与业务功能关系不大的代码,从而降低了两种代码的耦合性,达到易于维护和重用的目的。
当然我觉得,现在我们使用AOP已经不仅仅满足于日志、权限、异常处理、事务处理,可以将一些经常公用的代码抽出来作为切面,这个时候,当我们那个系统用就可以调用这个切面。当然我觉得这面也可以有跟业务有关的方法,同样可以作为切面使用。
AOP的简单解释:基本上每个方法都要用日志进行记录,那么如果按照面向对象的思路来说,就是每个对象都有记录日志这样一个行为。要在每个方法里添加日志的信息,必然会产生大量的重复代码,但可以将记录日志看作是一个横切面,所有对这些方法的调用都要经过这个横切面,然后在这个横切面进行记录日志的操作,这样就达到代码重用和易于维护的目的了,这就是AOP的思想。
AOP的两种方法:
1、作为构造器参数,通过参数将对象注入到另外一个对象中。
2、我们可以将依赖对象交给外部容器负责创建。就是依赖注入,依赖注入就是指在运行期,由外部容器动态地将依赖对象注入到组件中。
我们现在只用第2种方法实现:
实现方法:通过XML文件进行依赖注入,将方法拦截,拦截的方法通过三种方式来将切面切入方法中。
实现代码:
<span style="font-family:SimSun;font-size:18px;">using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebDemo { public interface IService { IList FindAll(); void Save(object entity); void AddString(string entity); void DeleteString(object entity); } }</span>
CategoryService.cs类集成了IService类:
<span style="font-family:SimSun;font-size:18px;">using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; using WebDemo.Models; namespace WebDemo { public class CategoryService : IService { public IList FindAll() { return new ArrayList(); } public void Save(object entity) { Console.WriteLine("保存:" + entity); } public void AddString(string entity) { //Console.WriteLine("添加:" + entity); SchoolDbContext dbContext = new SchoolDbContext(); UserInfo user = new UserInfo() { UName = entity, UPwd = "123" }; MemcacheHelper.Set(entity, user, DateTime.Now.AddMinutes(20)); dbContext.UserInfo.Add(user); dbContext.SaveChanges(); } public void DeleteString(object entity) { //Console.WriteLine("删除:" + entity); } } }</span>
在ProduciService.cs类,该类继承了IService:
<span style="font-family:SimSun;font-size:18px;">using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; using WebDemo.Models; using ITOO.Library.Core.Memcache; namespace WebDemo { public class ProductService : IService { public IList FindAll() { return new ArrayList(); } public void Save(object entity) { Console.WriteLine("保存:" + entity); } public void AddString(string entity) { //Console.WriteLine("添加:" + entity); string connectionString = "Data Source=192.168.24.233;user id=sa;password=123456;persist security info=True;database=" + entity; SchoolWoeDbContext dbContext1 = new SchoolWoeDbContext(connectionString); UserInfo m2 = new UserInfo(); UserInfo m1 = (UserInfo)ITOO.Library.Core.Memcache.MemcacheHelper.GetObject(m2, entity); dbContext1.UserInfo.Add(m1); dbContext1.SaveChanges(); } public void DeleteString(object entity) { //Console.WriteLine("删除:" + entity); } } }</span>
AfterAdvice类:
<span style="font-family:SimSun;font-size:18px;">using AopAlliance.Intercept; using Spring.Aop; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WebDemo { public class AfterAdvice : IAfterReturningAdvice { public void AfterReturning(object returnValue, System.Reflection.MethodInfo method, object[] args, object target) { Console.WriteLine("开始: " + method.Name); } } }</span>
<span style="font-family:SimSun;font-size:18px;">using System; using System.Collections.Generic; using System.Linq; using System.Text; using AopAlliance.Intercept; namespace WebDemo { public class AroundAdvice : IMethodInterceptor { public object Invoke(IMethodInvocation invocation) { Console.WriteLine("开始: " + invocation.TargetType.Name + "." + invocation.Method.Name); object result = invocation.Proceed(); Console.WriteLine("结束: " + invocation.TargetType.Name + "." + invocation.Method.Name); return result; } } }</span>
BeforeAdvice类:
<span style="font-family:SimSun;font-size:18px;">using AopAlliance.Intercept; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WebDemo { public class BeforeAdvice : Spring.Aop.IMethodBeforeAdvice,IMethodInterceptor { public object Invoke(IMethodInvocation invocation) { object result = invocation.Proceed(); Console.WriteLine("前置开始: " + invocation.TargetType.Name + "." + invocation.Method.Name); Console.WriteLine("前置结束: " + invocation.TargetType.Name + "." + invocation.Method.Name); return result; } public void Before(System.Reflection.MethodInfo method, object[] args, object target) { Console.WriteLine("前置结束: " + method.Name ); } } } </span>
在<configSections>节点中添加节点:
<span style="font-family:SimSun;font-size:18px;"> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> </sectionGroup></span>
<span style="font-family:SimSun;font-size:18px;"> <spring> <context> <resource uri="config://spring/objects" /> </context> <objects xmlns="http://www.springframework.net" xmlns:aop="http://www.springframework.net/aop"> <description>配置实现AOP</description> <!--必须要写的,不让不能拦截,对象名切入点:ObjectNameAutoProoxyCreateor--> <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop"> <property name="ObjectNames"> <list> <value>*Service</value> </list> </property> <property name="InterceptorNames"> <list> <!--<value>beforeAdvisor</value>--> <!--<value>afterAdvisor</value>--> <value>AroundAdvisor</value> </list> </property> </object> <!--加载 外部方法--> <!--<object id="afterAdvice" type="Common.AfterAdvice, Common"/>--> <object id="AroundAdvice" type="WebDemo.AroundAdvice, WebDemo"/> <!--<object id="beforeAdvice" type="Common.BeforeAdvice, Common"/>--> <!--配置 要拦截的类--> <object id="categoryService" type="WebDemo.ProductService, WebDemo"/> <object id="productService" type="WebDemo.ProductService, WebDemo"/> <!--必须要写的,不让不能拦截,对象名切入点:ObjectNameAutoProoxyCreateor--> <!--拦截使用的方法--> <!--<object id="beforeAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop">--> <!--<object id="afterAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> <property name="Advice" ref="afterAdvice"/>--> <object id="AroundAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> <property name="Advice" ref="AroundAdvice"/> <property name="MappedNames"> <list> <!--方法名的匹配--> <!--<value>*</value>--> <!--<value>Find*</value>--> <!--<value>Save*</value> <value>del*</value> <value>query*</value>--> <value>Add*</value> <value>Del*</value> </list> </property> </object> <!--<object id="beforeAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> <property name="Advice" ref="beforeAdvice"/> <property name="MappedNames"> <list> --> <!--方法名成的匹配--> <!-- <value>Find*</value> <value>Save*</value> </list> </property> </object>--> </objects> </spring> </span>
上面的配置就是我将所有的categoryService和productService中的Add和Del开头的方法全部拦截,之后通过AroundAdvice方法进行切入。这个时候,其实我们可以通过Memcached来讲所有的变量进行传递,这样就可以实现方法与方法之间的参数传递了。
在AOPController中:
<span style="font-family:SimSun;font-size:18px;">using Spring.Context; using Spring.Context.Support; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using WebDemo.Models; namespace WebDemo.Controllers { public class AOPController : Controller { // // GET: /AOP/ public ActionResult Index() { return View(); } public String Search(string item) { IApplicationContext ctx = ContextRegistry.GetContext(); IDictionary speakerDictionary = ctx.GetObjectsOfType(typeof(IService));//把所有的实现IService接口的类都加载出来 foreach (DictionaryEntry entry in speakerDictionary) { string name = (string)entry.Key; //获取类的方法名称 IService service = (IService)entry.Value; //获取该类 Console.WriteLine(name + " 拦截: "); service.AddString("qmx"); //需要通过AOP拦截的方法 } return "123"; } } }</span>
<span style="font-family:SimSun;font-size:18px;">@{ ViewBag.Title = "Index"; } <h2>Index</h2> <input type="button" id="button" value="拦截Add" onclick="add()" /> <script type="text/javascript"> function add() { var item = "qmx"; $.get("/AOP/Search/", { item: item }, function (string) { alert("添加成功!"); }); } </script></span>
AOP是一种思想,不是一种技术,这种思想通过容器的思想,以依赖注入的形式,将业务与业务之间进行了解耦,在很大程度上减少了我们的代码量。AOP的实现还有很多,但是大体上的本质是不会变的,变的可能就实现AOP的方式了。
标签:aop
原文地址:http://blog.csdn.net/qiumuxia0921/article/details/46228787