ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:41.54KB ,
资源ID:3812351      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3812351.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(02第二阶段面向切面编程AOP.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

02第二阶段面向切面编程AOP.docx

1、02第二阶段面向切面编程AOP十三、面向切面编程(基础篇)AOP即面向切面编程(Aspect Oriented Programming的缩写),是OOP(面向对象编程)的一种延续形式。是通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术,它从一个不同于OOP的角度来看待程序的结构:OOP将应用程序分解为一系列表现为继承关系的对象;AOP 则把程序分解为一系列方面(aspects)或者关注点(concerns)。AOP将诸如事务管理等本来横向分布在多个对象中的关注点进行了模块化处理(这些关注点也常称为横切(crosscutting)关注点)。在Spring.

2、NET中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的完成业务逻辑仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。下面我举个例子来说明这一切:场景:业务类CompanyManager在调用Save方法的时候需要调用SecurityManager类判断权限是否足够(图1)。图1 准备条件: public class CompanyDao public void Save() Console.WriteLine(保存数据); public

3、 interface ICompanyManager string UserName get; set; void Save(); public interface ISecurityManager bool IsPass(string userName); SecurityManager public class SecurityManager : ISecurityManager /*/ / 判断权限 / / / public bool IsPass(string userName) return userName = admin; 第一种实现方式,我们通常会这样做:直接在CompanyM

4、anager类中调用ISecurityManager接口的IsPass方法判断权限。 SimpleCompanyManagerpublic class SimpleCompanyManager : ICompanyManager 可通过外部注入的属性#region 可通过外部注入的属性 public string UserName get; set; public CompanyDao Dao get; set; #endregion public void Save() /判断权限 ISecurityManager security = new SecurityManager(); if (

5、security.IsPass(UserName) /执行业务方法 /. /调用DAO层方法 Dao.Save(); else /执行其它业务方法 Console.WriteLine(您没有该权限); 这样CompanyManager类与ISecurityManager或SecurityManager会发生业务性耦合。聪明的朋友会发现在GOF(设计模式)中有一种模式(代理模式)可以解除这种耦合。第二种实现方式,代理模式(Proxy Pattern):什么是代理模式?是给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况

6、下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入(图2)。图2CompanyManager public class CompanyManager : ICompanyManager 可通过外部注入的属性#region 可通过外部注入的属性 public string UserName get; set; public CompanyDao Dao get; set

7、; #endregion public void Save() /执行业务方法 /. /调用DAO层方法 Dao.Save(); CompanyProxyManager public class CompanyProxyManager : ICompanyManager public string UserName get; set; private ICompanyManager target = new CompanyManager(); public void Save() /判断权限 ISecurityManager security = new SecurityManager();

8、if (security.IsPass(UserName) /调用目标对象Save方法 target.Save(); else Console.WriteLine(您没有该权限); 这样,CompanyManager类就不必与判断权限的类SecurityManager耦合,但是这种方式实现起来比较麻烦。 第三种实现方式,Spring.NET提供的AOP:AopAlliance.Intercept.IMethodInterceptor接口和ProxyFactory类的组合。AroundAdvice public class AroundAdvice : IMethodInterceptor /权

9、限系统类(可外部注入) private ISecurityManager manager = new Service.SecurityManager(); public object Invoke(IMethodInvocation invocation) /拦截Save方法 if (invocation.Method.Name = Save) ICompanyManager target = (ICompanyManager)invocation.Target; return manager.IsPass(target.UserName) ? invocation.Proceed() : n

10、ull; else return invocation.Proceed(); Program class Program static void Main(string args) ICompanyManager target = new CompanyManager() Dao = new CompanyDao(), UserName = admin ; ProxyFactory factory = new ProxyFactory(target); factory.AddAdvice(new AroundAdvice(); ICompanyManager manager = (ICompa

11、nyManager)factory.GetProxy(); manager.Save(); Console.ReadLine(); 输出:保存数据 Spring.NET利用System.Reflection.Emit命名空间下的类在运行时动态创建IL代码来生成AOP代理。这使得代理(的创建)非常高效,并且不受任何继承层次的限制。十四、AOP的概念(基础篇)上篇我们简单的了解了AOP的应用场景,知道AOP编程的重要性。这篇我们先看一段代码,来开始今天的学习。回顾与上篇类似的代码:SecurityService类的IsPass判断用户名为“admin”则有权限保存数据。OrderService为保

12、存数据的类,实现IOrderService接口。Code public class SecurityService public bool IsPass(string userName) return userName = admin; public interface IOrderService string UserName get; set; object Save(object id); 实现部分OrderService public class OrderService : IOrderService public string UserName get; set; public o

13、bject Save(object id) return 保存: + id.ToString(); AroundAdvise public class AroundAdvise : IMethodInterceptor public object Invoke(IMethodInvocation invocation) IOrderService target = (IOrderService)invocation.Target; SecurityService manager = new SecurityService(); if (manager.IsPass(target.UserNam

14、e) return invocation.Proceed(); else return null; 客户端部分:Program class Program static void Main(string args) ProxyFactory factory = new ProxyFactory(new OrderService() UserName = admin ); factory.AddAdvice(new AroundAdvise(); IOrderService service = (IOrderService)factory.GetProxy(); object result =

15、service.Save(1); Console.WriteLine(result); Console.ReadLine(); 输出:保存:1 通过上篇的学习,我们知道,什么是AOP面向切面的编程。在AOP(面向切面的编程)中,我们编写程序时,首先思考要对程序中哪些方法进行拦截,拦截到这些方法后又要做哪些业务处理。这些关注过程,我们称之为:横切性关注点。由“横切性关注点”引申出以下概念:Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象。程序里的切面就是AroundAdvise类的实现部分。joinpoint

16、(连接点):所谓连接点是指那些被拦截到的点。在Spring.NET中,连接点指的是方法,因为Spring.NET只支持方法类型的连接点,实际上joinpoint(连接点)还可以是字段或类构造器。程序里的连接点就是拦截到的方法,如OrderService类的Save方法。Pointcut(切入点):所谓切入点是指我们要对那些joinpoint(连接点)进行拦截的定义。程序里没有使用invocation.Method来判断拦截哪些方式,而Pointcut(切入点)就是对所有方法进行拦截。Advice(通知):所谓通知是指拦截到joinpoint(连接点)之后所要做的事情就是通知.通知分为前置通知,

17、后置通知,异常通知,环绕通知。AroundAdvise继承AopAlliance.Intercept.IMethodInterceptor 接口,程序里使用的是环绕通知。Target(目标对象):代理的目标对象。程序里的目标对象就是OrderService类,我们通过ProxyFactory factory = new ProxyFactory(new OrderService() UserName = admin );这句代码确定了目标对象是OrderService。 AOP代理(AOP proxy):由AOP框架在将通知应用于目标对象后创建的对象。程序里通过GetProxy()方法创建出的

18、代理对象。Weave(织入):指将切面(aspect)应用到目标对象(target)对象并导致代理(proxy)对象创建的过程称为织入。正如程序里所应用的,OrderService类不具备判断权限的功能,我们将判断权限的功能SecurityService类的IsPass方法应用到目标对象的过程。Introduction(引入):在不修改类代码的前提下,Introduction(引入):可以在运行期为类动态地添加一些方法或字段。程序里在没有修改OrderService类,而是在运行期把判断权限的功能通过ProxyFactory的AddAdvice方法动态的增加进去。这些术语不属于Spring.N

19、ET,而属于整个AOP编程。所谓AOP,我的理解就是应该是这样一个过程,首先需要定义一个切面,这个切面是一个类,里面的方法就是关注点(也是通知),或者说里面的方法就是用来在执行目标对象方法时需要执行的前置通知,后置通知,异常通知,最终通知,环绕通知等等。有了切面和通知,要应用到目标对象,就需要定义这些通知的切入点,换句话说就是需要对哪些方法进行拦截,而这些被拦截的方法就是连接点,所谓连接点也就是在动态执行过程,被织入切面的方法(至少在Spring.NET中只能对方法进行拦截)。因此,在动态过程中通知的执行就属于织入过程,而被织入这些通知的对象就是目标对象了。十五、AOP的通知类型(基础篇)上篇

20、我们学习了AOP的基本概念,我们回顾一下上篇提到的Advice(通知):所谓通知是指拦截到joinpoint(连接点)之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,环绕通知。Spring.NET的通知既可由某个类的所有对象共享,也可由该类型的单个实例独占。共享的通知称为基于类型(per-class)的通知,而独占的通知称为基于实例(per-instance)的通知。基于类型的通知最为常用。很多常用功能很适合用基于类型的通知实现,比如说事务。它们不依赖于目标对象的状态,也不会向目标对象添加新状态,仅仅对方法及其参数进行操作。基于实例的通知比较适合做引入(introduction

21、s)。此时通知可以向目标对象添加状态。在AOP代理中,可以同时使用基于类型和基于实例的通知。Spring.NET和spring框架略有不同,只有四种通知类型,没有spring框架的最终通知(目前我还没有实现最终通知,如果有朋友实现的话,可以给我留言)。一、拦截环绕通知(around advice):Spring.NET中最基本的通知类型是拦截环绕通知(interception around advice),即方法拦截器。拦截环绕通知继承IMethodInterceptor接口。注意其中IMethodInvocation.Proceed()方法的调用。该方法会依次调用拦截器链上的其它拦截器。大部

22、分拦截器都需要调用这个方法并返回它的返回值。当然,也可以不调用Proceed方法,而返回一个其它值或抛出一个异常,但一般不太会这么做。二、前置通知(before advise):是在IMethodInterceptor.Proceed()方法调用前的通知。继承自IMethodBeforeAdvice接口。三、异常通知(throws advise):是在IMethodInterceptor.Proceed()方法调用时发生异常的通知。继承自IthrowsAdvice接口。IthrowsAdvice接口没有定义任何方法:它是一个标识接口(按:之所以用标识接口,原因有二:1、在通知方法中,只有最后一

23、个参数是必须的。如果声明为接口的方法,参数列表就被固定了。2、如果第一个原因可以用重载的接口方法解决,那么这个原因就是使用标识接口的充分原因了:实现此接口的类必须声明一或多个通知方法,接口方法做不到这一点),用以表明实现它的类声明了一或多个强类型的异常通知方法。四、后置通知(after returning advise):是在IMethodInterceptor.Proceed()方法调用后的通知。继承自IAfterReturningAdvice接口。后置通知对切入点的执行没有影响,如果通知抛出异常,就会沿拦截器链向上抛出,从而中断拦截器链的继续执行。 代码实现:准备条件 四种通知:Aroun

24、dAdvise /*/ / 环绕通知 / public class AroundAdvise : IMethodInterceptor public object Invoke(IMethodInvocation invocation) Console.Out.WriteLine(string.Format( 环绕通知: 调用的方法 0, invocation.Method.Name); Console.WriteLine(); object returnValue = null; try returnValue = invocation.Proceed(); catch Console.Ou

25、t.WriteLine( 环绕通知: 发生异常); Console.WriteLine(); Console.Out.WriteLine(String.Format( 环绕通知: 返回值 0, returnValue); return returnValue; BeforeAdvise /*/ / 前置通知 / public class BeforeAdvise : IMethodBeforeAdvice public void Before(MethodInfo method, object args, object target) Console.Out.WriteLine( 前置通知:

26、调用的方法名 : + method.Name); Console.Out.WriteLine( 前置通知: 目标 : + target); Console.Out.WriteLine( 前置通知: 参数为 : ); if (args != null) foreach (object arg in args) Console.Out.WriteLine(t: + arg); Console.WriteLine(); ThrowsAdvise /*/ / 异常通知 / public class ThrowsAdvise : IThrowsAdvice public void AfterThrowi

27、ng(Exception ex) string errorMsg = string.Format( 异常通知: 方法抛出的异常 : 0, ex.Message); Console.Error.WriteLine(errorMsg); Console.WriteLine(); AfterReturningAdvise /*/ / 后置通知 / public class AfterReturningAdvise : IAfterReturningAdvice public void AfterReturning(object returnValue, MethodInfo method, obje

28、ct args, object target) Console.Out.WriteLine( 后置通知: 方法调用成功,方法名 : + method.Name); Console.Out.WriteLine( 后置通知: 目标为 : + target); Console.Out.WriteLine( 后置通知: 参数 : ); if (args != null) foreach (object arg in args) Console.Out.WriteLine(t: + arg); Console.Out.WriteLine( 后置通知: 返回值是 : + returnValue); Console.WriteLine(); 接口: public interface IOrderService object Save(object id); 一、没有异常的情况OrderService public class OrderService : IOrderService /*/ / 拦截该方法 / / / public object Save(object id) /thro

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1