浅析Spring.net 中的Aop使用
一. 什么是AOP
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加 功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例 如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并 不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
切面(Aspect)
切面是你要实现的交叉功能。它是应用系统模块化的一个切面或领域。切面的最常见(虽然简单)例子是日志记录。日志记录在系统中到处需要用到,利用继承来重用日志模块不适合。然而,你可以创建一个日志记录切面,并且使用AOP在系统中应用。
连接点(Joinpoint)
连接点是应用程序执行过程中插入切面的地点。这个地点可以是方法调用,异常抛出,或者甚至是要修改的字段。切面代码在这些地方插入到你的应用流程中,添加新的行为。
通知(Advice)
通知切面的实际实现。它通知应用系统新的行为。在日志例子中,日志通知包含了实现实际日志功能的代码,如向日志文件写日志。通知在连接点插入到应用系统中。
切入点(Pointcut)
切入点定义了通知应该应用在哪些连接点。通知可以应用到AOP框架支持的任何连接点。当然,你并不希望把所有切面应用到所有可能的连接点上。切入点让你指定通知应用到什么地方。通常通过指定类名和方法名,或者匹配类名和方法名式样的正则表达式来指定切入点。一些AOP框架允许动态创建切入点,在运行时根据条件决定是否应用切面,如方法参数值。
引入(Introduction)
引入允许你为已存在类添加新方法和属性。例如,你可以创建一个稽查通知来记录对象的最后修改时间。只要用一个方法setLastMofified(Date)以及一个保存这个状态的变量。可以在不改变已存在类的情况下将这个引入,给他们新的行为和状态。
目标对象(Target)
目标对象是被通知对象。它既可以是你编写的类也可以是你要添加制定行为的第三方类。如果没有AOP,这个类就必须要包含它的主要逻辑以及其他交叉业务逻辑。有了AOP,目标对象就可以全身心地关注主要业务,忘记应用其上的通知。
代理(Proxy)
代理是将通知应用到目标对象后创建的对象。对于客户对象来说,目标对象(应用AOP之前的对象)和代理对象(应用AOP之后的对象)是一样的。也就是,应用系统的其他部分不用为了支持代理对象而改变。
织入 (Weaving)
织入是将切面应用到目标对象从而创建一个新的代理对象的过程。切面在指定接入点被织入到目标对象中。
二. 几个重要接口
用于找到用于通知的相关的类型和方法
1 public interface IPointcut 2 3 { 4 5 ITypeFilter TypeFilter { get; } 6 7 IMethodMatcher MethodMatcher { get; } 8 9 }
用于匹配相关类型
1 public interface ITypeFilter 2 3 { 4 5 bool Matches(Type type); 6 7 } 8 9 public interface IMethodMatcher 10 11 { 12 13 bool IsRuntime { get; } 14 15 bool Matches(MethodInfo method, Type targetType); 16 17 bool Matches(MethodInfo method, Type targetType, object[] args); 18 19 }
Matches(MethodInfo, Type)方法用来测试这个切入点是否匹配目标类的指定方法。这将在AOP代理被创建的时候执行,这样可以避免在每次方法调用的时候都执行。如果两个参数的matches方法对于一个给定的方法返回true,并且IMethodMatcher接口的IsRuntime方法也返回true,那么有三个参数的matches方法将在每个方法调用时被调用. 这使得切入点在通知将被执行前可以查看传入到方法的参数。
绝大多数的IMethodMatcher接口是static的,这也就意味着它们的IsRuntime属性返回false.在这种情况下,有三个参数的Matches方法将永远不会被调用.
三. 通知
3.1 通知生命周期
3.2 通知类型
一、拦截环绕通知(around advice):Spring.NET中最基本的通知类型是拦截环绕通知(interception around advice),即方法拦截器。拦截环绕通知继承IMethodInterceptor接口。注意其中IMethodInvocation.Proceed()方法的调用。该方法会依次调用拦截器链上的其它拦截器。大部分拦截器都需要调用这个方法并返回它的返回值。当然,也可以不调用Proceed方法,而返回一个其它值或抛出一个异常,但一般不太会这么做。
二、前置通知(before advise):是在IMethodInterceptor.Proceed()方法调用前的通知。继承自IMethodBeforeAdvice接口。
三、异常通知(throws advise):是在IMethodInterceptor.Proceed()方法调用时发生异常的通知。继承自IthrowsAdvice接口。IthrowsAdvice接口没有定义任何方法:它是一个标识接口(按:之所以用标识接口,原因有二:1、在通知方法中,只有最后一个参数是必须的。如果声明为接口的方法,参数列表就被固定了。2、如果第一个原因可以用重载的接口方法解决,那么这个原因就是使用标识接口的充分原因了:实现此接口的类必须声明一或多个通知方法,接口方法做不到这一点),用以表明实现它的类声明了一或多个强类型的异常通知方法。
四、后置通知(after returning advise):是在IMethodInterceptor.Proceed()方法调用后的通知。继承自IAfterReturningAdvice接口。后置通知对切入点的执行没有影响,如果通知抛出异常,就会沿拦截器链向上抛出,从而中断拦截器链的继续执行。
3.2.1 Interception Around Advice(环绕拦截通知,后面的讲解以环绕拦截通知为例子)
方法拦截器接口
1 public interface IMethodInterceptor : IInterceptor 2 3 { 4 5 object Invoke(IMethodInvocation invocation); 6 7 }
模拟环绕拦截通知
1 public class DebugInterceptor : IMethodInterceptor 2 { 3 4 public object Invoke(IMethodInvocation invocation) 5 { 6 7 Console.WriteLine("Before: invocation=[{0}]", invocation); 8 9 object rval = invocation.Proceed(); 10 11 Console.WriteLine("Invocation returned"); 12 13 return rval; 14 15 } 16 17 } 18 19
注意 IMethodInvocation 的 Proceed 方法,proceed方法返回方法的返回值.
四. 切入点操作
4.1 静态切入点
4.1.1 ProxyFactoryObject 显式创建AOP代理
1 <object id="UserValidateTarget" type="Stephen.SpringNet.AOPSample.Servcies.Impl.UserValidate, Servcies"></object> 2 3 <object id="RoundInterceptor" type="Stephen.SpringNet.AOPSample.Servcies.Interceptor.RoundInterceptor, Servcies"></object> 4 5 <object id="UserValidateProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> 6 7 <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> 8 9 <property name="target" ref="UserValidateTarget"/> 10 11 <property name="interceptorNames"> 12 13 <list> 14 15 <value>RoundInterceptor</value> 16 17 </list> 18 19 </property> 20 21 </object>
不过由于显式的创建AOP在要创建多个代理的时候需要重复的配置因此Spring提供了自动代理
4.1.2 ObjectNameAutoProxyCreator 对象名称自动切入点
可以用特定的文本值或通配符匹配目标对象的名称,并为满足条件的目标对象创建AOP代理。该类支持模式匹配字符串,如:"*name","name*",”*name*“和精确文本如"name"。我们可以通过下面这个简单的例子了解一下自动代理的功能。
1 <object id="IValidateProxy" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop"> 2 3 <property name="ObjectNames"> 4 5 <list> 6 7 <value>*Validate</value> 8 9 </list> 10 11 </property> 12 13 <property name="InterceptorNames" value="RoundInterceptor"></property> 14 15 </object>
1 [TestMethod] 2 3 public void ObjectNameAutoProxyCreatorMethodTest() 4 5 { 6 7 var context = ContextRegistry.GetContext(); 8 9 IDictionary validates = context.GetObjectsOfType(typeof(IValidateService)); 10 11 foreach (DictionaryEntry validate in validates) 12 13 { 14 15 ((IValidateService) validate.Value).Validate(null); 16 17 } 18 19 }
执行结果
ObjectNameAutoProxyCreatorMethodTest : Passed
Method:Validate开始执行
Method:Validate执行完毕
4.1.3 SdkRegularExpressionMethodPointcut 通过正则表达式来匹配需要执行的类或方法
1 <object id="ValidatePointCut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop"> 2 <property name="Pattern" value="UserValidate.Advance*"></property> 3 </object> 4 <aop:config> 5 <aop:advisor advice-ref="RoundInterceptor" pointcut-ref="ValidatePointCut"/> 6 </aop:config>
pattern 的属性 UserValidate.Advance* 表示 匹配 UserValidate 类中的以Advance开头的方法
4.1.4 DefaultAdvisorAutoProxyCreator+RegularExpressionMethodPointcutAdvisor 创建正则表达式AOP
1 <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/> <object id="ValidateRegularExpressionPointCut" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop"> 2 <property name="advice" ref="RoundInterceptor"/> 3 <property name="patterns"> 4 <list> 5 <value>UserValidate.Advance*</value> 6 </list> 7 </property> 8 </object>
4.1.5 特性Aop
可以通过Attribute类来实现AOP
[AttributeUsage(AttributeTargets.Method)]public class AopAttribute:Attribute{ }
1 <object id="aroundAdvisor" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop"> 2 3 <property name="Advice" ref="RoundInterceptor"/> 4 5 <property name="Attribute" 6 7 value ="Stephen.SpringNet.AOPSample.Servcies.AopAttribute, Servcies" /> 8 9 </object> 10 11 12 13 <object id="ValidateAttributeProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"> 14 15 <property name="proxyInterfaces" value="Stephen.SpringNet.AOPSample.Servcies.IValidateService"/> 16 17 <property name="target" ref="UserValidateTarget"/> 18 19 <property name="interceptorNames"> 20 21 <list> 22 23 <value>aroundAdvisor</value> 24 25 </list> 26 27 </property> 28 29 </object>
转载于:https://www.cnblogs.com/vipyoumay/archive/2012/07/07/2580420.html
浅析Spring.net 中的Aop使用相关推荐
- Spring Boot中使用AOP统一处理Web请求日志
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...
- Spring MVC 中使用AOP 进行统一日志管理--XML配置实现
1.介绍 上一篇博客写了使用AOP进行统一日志管理的注解版实现,今天写一下使用XML配置实现版本,与上篇不同的是上次我们记录的Controller层日志,这次我们记录的是Service层的日志.使用的 ...
- Spring MVC 中使用AOP 进行事务管理--XML配置实现
1.今天写一篇使用AOP进行事务管理的示例,关于事务首先需要了解以下几点 (1)事务的特性 原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完 ...
- Spring boot中使用aop详解
aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案. 现在就以springboot中aop的使用来了解一下aop. 一:使用aop来完成全局请求日志处理 创建一个sp ...
- Spring boot中使用aop初了解
aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案. 现在就以springboot中aop的使用来了解一下aop. 一:使用aop来完成全局请求日志处理 创建一个sp ...
- Spring框架(中) AOP
Spring(中) AOP (一)代理模式 1.静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者是继承相同父类. 举例: package co ...
- Spring框架中的核心技术之AOP
目录 1. 什么是AOP? 2. 实现AOP技术的框架有哪些? 2.1 Spring框架中的AOP技术 2.2 Aspectj框架 2.3 小结 3. Aspectj框架中的使用AOP的方式 4. A ...
- spring框架中JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言 JDK动态代理实现原理(jdk8):https://blog.csdn.net ...
- 【springboot中使用aop的具体步骤和示例】
1.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spri ...
- 一文读懂Spring中的AOP机制
一.前言 这一篇我们来说一下 Spring 中的 AOP 机制,为啥说完注解的原理然后又要说 AOP 机制呢? 1.标记日志打印的自定义注解 @Target({ElementType.METHOD}) ...
最新文章
- DotNetNuke与MemberShip的结合(五年版)第三步修改HttpModule.DNNMembership
- C# 连接SQL数据库字符串
- python精通书籍-清华学霸整理,Python入门到精通这几本书帮你快速入行
- WIN8、WIN7访问Windows Server 2003服务器的数据库速度很慢、远程速度很慢的解决方法...
- 针对行业需求服务优质客户 ,网易云信助金融行业“网上冲浪”
- matlab 叠加 area,[转载]matlab学习——area填色图
- 淘宝NPM镜像、cnmp
- mysql show slave_Mysql复制 show slave status
- 挂起某线程命令 Linux,linux 线程挂起恢复的简单示例
- 5.jQueryAjax
- oracle备份恢复之rman恢复到异机(二)
- android edittext换行位置不变,Android EditText使用自动换行但无硬性返回
- linux系统管理Linux系统实验,实验三 linux系统管理.doc
- 孙正义宣布回购55亿美元股票,软银股价创10年最大单日涨幅...
- 微型计算机乘法部件位于,组成原理复习题8.doc
- ghost系统之优劣?
- 惠普136nw打印机清零_惠普打印机硒鼓清零方法是怎样的
- 2022年全球与中国网络处理器市场现状及未来发展趋势
- Sobel边缘检测算子数学原理再学习
- 次梯度(subgradient)方法
热门文章
- ArcGIS加载Excel数据连接到数据库失败的解决办法
- IDEA中如何将springboot项目打包成war包,部署在tomcat中
- Kubernetes核心技术--Pod,Label,Volume,Service,Deployment详解
- ORACLE利用scn赚钱,在Oracle中增进SCN及案例介绍
- Flink kafka source sink 源码解析
- 周五,分享一个好消息
- java ajax传值到后台_java ajax发送数据到后台,中文乱码
- 冯诺依曼提出的三个计算机改进理论,冯诺依曼体系结构的计算机..docx
- 二次拟合r方_使用SPSS拟合曲线
- c++生成随机数_C 语言产生随机数的方法