




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
,面向切面编程,主讲人:孙鑫,,AOP介绍,AOP全称是AspectOrientedProgramming,中文翻译为面向切面编程。,,AOP术语,Aspect(切面),切面就是你要实现的横切功能。Jointpoint(连接点),连接点是应用程序执行过程中插入切面的地点(执行点)。这个地点可以是方法调用,异常抛出,或者甚至是要修改的字段。切面代码在这些地方插入你的应用流程中,添加新的行为。Advice(通知),通知是切面的实际实现。它通知应用系统新的行为。在日志例子中,日志通知(loggingadvice)包含了实际实现日志功能的代码,例如向日志文件中写日志。通知在连接点被插入到应用程序。PointCut(切入点),切入点定义了通知应该应用到哪些连接点。通知可以应用到AOP框架支持的任何连接点。Introduction(引入),引入允许你为已经存在的类添加新方法和属性。TargetObject,目标对象,即被代理的对象。AOPProxy,AOP代理。代理是将通知应用到目标对象后创建的对象。AOP代理,AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。Weaving(织入),织入是将切面应用到目标对象从而创建一个新的代理对象的过程。切面在指定的连接点被织入到目标对象中。分为静态织入(AspectJ)和动态织入(SpringAOP)。,,,Spring中的通知类型,,BeforeAdvice,MethodBeforeAdvice在方法调用之前被调用,这样的Advice不能够阻止方法调用的进行,除非它抛出一个异常。MethodBeforeAdvice接口只有一个方法:voidbefore(Methodmethod,Objectargs,Objecttarget)throwsThrowable参数method表示被调用的方法,参数args表示被调用方法的参数,参数target表示方法调用的目标,可以是null。注意返回的类型是void。Before通知可以在连接点执行之前插入自定义的行为,但是不能改变返回值。如果一个beforeadvice抛出一个异常,这将中断拦截器链进一步的执行。这个异常将沿着拦截器链向上传播。如果这个异常是unchecked的(RuntimeException),或者出现在被调用方法的签名中(即目标方法声明抛出的异常),那么它将会被直接传递给客户代码;否则,它将被AOP代理包装到一个unchecked的异常中。Beforeadvice可以和任何切入点一起使用。,,AfterReturningadvice,Afterreturningadvice只有在方法正常返回时被调用,如果方法执行抛出了异常,那么该advice将不会被调用。这样的advice可以看见返回值,但是不能改变它。Afterreturning通知可以访问返回值(不能改变)、被调用的方法、方法的参数和目标对象。AfterReturningAdvice接口只有一个方法:voidafterReturning(ObjectreturnValue,Methodmethod,Objectargs,Objecttarget)参数returnValue表示方法的返回值,method表示被调用的方法,参数args表示被调用方法的参数,参数target表示方法调用的目标,可以是null。Afterreturningadvice不会改变执行的路径。如果它抛出一个异常,这个异常将取代返回值沿着拦截器链被向上抛出。Afterreturningadvice可以和任何切入点一起使用。,,Interceptionaroundadvice,Spring中最基本的advice类型是interceptionaroundadvice。Spring中使用方法拦截的aroundadvice是和AOP联盟接口相兼容的。实现aroundadvice的MethodInterceptors需要实现下面的接口:ercept.MethodInterceptorpublicinterfaceMethodInterceptorextendsInterceptorObjectinvoke(MethodInvocationinvocation)throwsThrowable;invoke()方法的MethodInvocation参数暴露了被调用的方法、目标连接点、AOP代理以及传递给被调用方法的参数。invoke()方法应该返回调用的结果:即连接点的返回值。MethodInterceptor接口和前面介绍的两种通知有两个重要区别:1、MethodInterceptor能够控制目标方法是否真的被调用。通过调用MethodIceed()方法来调用目标方法。这一点不同于MethodBeforeAdvice,目标方法总是会被调用,除非抛出异常。2、MethodInterceptor让你可以控制返回的对象。也就是说你可以返回一个与proceed()方法返回对象完全不同的对象。使用AfterReturningAdvice你可以获得返回的对象,但是你不能返回一个不同的对象。而MethodInterceptor提供了这个功能,更加灵活。,,Throwsadvice,ThrowsAdvice接口是一个标识接口,在这个接口上没有任何方法,因为方法通过反射来调用。实现类必须至少有一个如下形式的方法:voidafterThrowing(Throwablethrowable)voidafterThrowing(Methodmethod,Objectargs,Objecttarget,Throwablethrowable)如果你想要了解更多的有关连接点的信息,可以使用第2个方法。如果连接点抛出异常,Throwsadvice将在连接点返回后被调用。可以在一个类里组合任意数量的throws通知方法。Throwsadvice可以和任何切入点一起使用。注意:Throwsadvice只能够访问异常信息,并不能阻止异常继续传递。,,Introductionadvice,Spring将introductionadvice看作一种特殊类型的拦截advice。Introduction需要实现IntroductionAdvisor和IntroductionInterceptor接口:publicinterfaceIntroductionInterceptorextendsMethodInterceptorbooleanimplementsInterface(Classintf);Introductionadvice不能和任何切入点一起使用,因为它是应用在类级别而不是方法级别。,,Spring的切入点,切入点决定了一个特定类的特定方法是否满足一条特定规则。如果一个方法确实符合,通知就被应用到该方法上。Spring的切入点可以让我们以一种灵活的方法定义在什么地方将通知织入到我们的类中。,,在Spring中定义切入点,通知是基于目标类和方法的特性来织入的,例如类名和方法签名。Spring的切入点框架的核心接口是P.springframework.aop.Pointcut是最核心的接口,用来将通知应用到特定的类和方法。完整的接口定义如下:publicinterfacePointcutClassFiltergetClassFilter();MethodMatchergetMethodMatcher();将Pointcut接口分成两个部分有利于重用类和方法的匹配部分,并且进行细粒度的组合操作(如和另一个方法匹配器执行一个“并(union)操作”)。ClassFilter接口用来将切入点限定在一个给定的类集合中(ClassFilter接口决定了一个类是否符合通知的要求)。如果ClassFilter接口的matches()方法总是返回true,那么所有的目标类都将被匹配。publicinterfaceClassFilterbooleanmatches(Classclazz);实现这个接口的类决定了以参数传入进来的类是否应该被通知。实现这个接口的类一般根据类名决定,但这并不是必须的。这个接口包含了一个简单的ClassFilter接口的实现ClassFilter.TRUE。它是规范的适合任何类的ClassFilter实例,它可以被用于创建只考虑方法匹配时的切入点。,,在Spring中定义切入点,MethodMatcher接口通常更重要。完整的接口定义如下:publicinterfaceMethodMatcherbooleanmatches(Methodm,ClasstargetClass);booleanisRuntime();booleanmatches(Methodm,ClasstargetClass,Objectargs);这个接口有三个方法,但是每个方法用在被代理对象生命周期的特定时刻。matches(Methodm,ClasstargetClass)方法根据目标类和方法决定一个方法是否该被通知。因此可以静态地判断,所以可以在AOP代理被创建的时候调用一次这个方法。这个方法的结果最终决定了通知是否被织入。如果matches(Method,Class)方法返回true,isRunime()被调用来决定MethodMatcher的类型。有两种类型:静态的和动态的。静态切入点的意思是通知总是被执行。如果一个切入点是静态的,isRuntime()方法应该返回false。动态切入点根据运行时方法的参数值决定通知是否应该被执行。如果切入点是动态的,isRuntime()方法应该返回true。和matches(Method,Class)方法一样,isRuntime()方法也是只在代理类被创建时调用一次。如果一个切入点是静态的,matches(Method,Class,Object)方法永远不会被调用,因为不需要根据参数运行时值来决定通知是否需要被应用。对于动态切入点,目标方法每次被调用的时候,matches(Method,Class,Object)方法就要被调用。每次这个方法被调用的时候,就增加了运行时的负担,因此要尽可能的使用静态切入点。matches(Method,Class)方法被用来测试这个切入点是否匹配目标类的给定方法。这个测试可以在AOP代理创建的时候执行,避免在所有方法调用时都需要进行测试。如果2个参数的匹配方法对某个方法返回true,并且MethodMatcher的isRuntime()也返回true,那么3个参数的匹配方法将在每次方法调用的时候被调用。这使切入点能够在目标通知被执行之前立即查看传递给方法调用的参数。大部分MethodMatcher都是静态的,意味着isRuntime()方法返回false。这种情况下3个参数的匹配方法永远不会被调用。,,理解Advisor,大多数切面是由定义切面行为的通知和定义切面在什么地方执行的切入点组合而成的。Spring认识到这一点,提供了Advisor,它把通知和切入点组合到一个对象中。更确切地说,PointcutAdvisor接口提供了这些功能。在Spring中,一个advisor就是一个aspect的完整的模块化表示。一般地,一个advisor包括一个通知和一个切入点。org.springframework.aop.PointcutAdvisor接口继承自Advisor接口,定义的方法如下:PointcutgetPointcut()AdvicegetAdvice()booleanisPerInstance()/这个方法当前并没有被Spring框架所使用。大多数Spring自带的切入点都有一个对应的PointcutAdvisor。这样方便你在一个地方定义切入点和通知。,,使用Spring的静态切入点,正如前面介绍的,由于静态切入点只在代理创建的时候执行一次而不是在运行期间每次方法调用都执行,所以性能比动态切入点好,是首选的切入点方式。Spring为创建静态切入点提供了方便的父类:org.springframework.aop.support.StaticMethodMatcherPointcut。所以,如果你想创建一个定制的静态切入点,你只要继承这个类,实现下面的方法就可以了。publicbooleanmatches(Methodmethod,ClasstargetClass)StaticMethodMatcherPointcut继承自StaticMethodMatcher,并实现了Pointcut接口。注意StaticMethodMatcher中的matches(Method,Class,Object)方法和isRuntime()方法都声明为final,也就是说在子类中不能重写这两个方法。,,NameMatchMethodPointcut,NameMatchMethodPointcut继承自StaticMethodMatcherPointcut,用于简单的方法名字匹配。在这个类中有两个方法值得注意:publicvoidsetMappedName(String)publicvoidsetMappedName(String)当调用方法的名字与设置的映射名字匹配时,这个切入点才匹配。你可以使用明确的方法名也可以在名字的起始和结束处使用通配符*。例如,设置mappedName属性的值为set*将匹配所有的set方法。注意这种匹配只适用于方法自身而不包括类名。NameMatchMethodPointcut对应的PointcutAdvisor是NameMatchMethodPointcutAdvisor。配置的例子如下:lo*注意:一个Advisor只能有一个Advice,所以在advice属性中,不能使用元素,并且这个属性需要的是一个Advice对象的引用,而不是名字。,,正则表达式切入点,Spring的正则表达式切入点Perl5RegexpMethodPointcut和JdkRegexpMethodPointcut让你利用正则表达式的力量来定义切入点。这让你能够使用Perl样式的正则表达式来定义模式,来匹配你想要的方法。Perl5RegexpMethodPointcut对应的PointcutAdvisor是RegexpMethodPointcutAdvisor。使用RegexpMethodPointcutAdvisor类,可以委派给任何的AbstractRegexpMethodPointcut类的子类,就像Perl5RegexpMethodPointcut或者JdkRegexpMethodPointcut。为了选择特定的一个,或者覆盖createPointcut,或者设置“perl5”标记(调用setPerl5方法)。缺省情况下,在JDK1.4及之后的版本,将使用JdkRegexpMethodPointcut;在JDK1.3,将使用Perl5RegexpMethodPointcut(在classpath环境变量中要配置JakartaORO类库)。可以通过指定“perl5”属性来强制使用Perl5RegexpMethodPointcut。RegexpMethodPointcutAdvisor类的createPointcut()方法如下:protectedAbstractRegexpMethodPointcutcreatePointcut()创建实际的切入点:缺省情况下,如果Perl5语法是强制使用的,或者运行在JDK1.3上,Perl5RegexpMethodPointcut对象将被创建。,,正则表达式切入点,配置RegexpMethodPointcutAdvisor的例子如下:.*lo.+in+这个正则表达式的意思是,我们的切入点应该匹配的方法是,任何类的以lo开头,后面至少有一个字符,然后后面至少有一个in的方法。正则表达式为你提供了一种比NameMatchMethodPointcut更加有表达力的定义切入点的方法。,,使用动态切入点,动态切入点的计算代价比静态切入点高的多。它们不仅考虑静态信息,还要考虑方法的参数。这意味着它们必须在每次方法调用的时候都被计算;并且不能缓存结果,因为参数是变化的。在有些情况下切入点需要判断运行时属性的值。Spring提供了一种内置的动态切入点:ControlFlowPointcut。这个切入点根据当前线程调用栈中的信息来匹配方法。Spring的控制流切入点概念上和AspectJ的cflow切入点一致,虽然没有其那么强大(当前没有办法指定一个切入点在另一个切入点后执行)。一个控制流切入点匹配当前的调用栈。例如,连接点被com.mycompany.web包或者SomeCaller类中一个方法调用的时候,触发该切入点。控制流切入点的实现类是org.springframework.aop.support.ControlFlowPointcut。ControlFlowPointcut有如下的两个构造方法:publicControlFlowPointcut(Classclazz)构造一个匹配clazz下的所有控制流的新的切入点。publicControlFlowPointcut(Classclazz,StringmethodName)构造一个匹配给定类中给定方法下的所有调用的新的切入点。如果methodName是null,则匹配这个类下的所有控制流。,,使用动态切入点,配置ControlFlowPointcut的例子:.sunxin.spring.lesson04.TestSpringAoptestMyAdvisor注意:控制流切入点是动态切入点中计算代价最高的。Java1.4中,它的运行开销是其他动态切入点的5倍。在Java1.3中则超过10倍。正如前面介绍的,你也可以实现MethodMatcher接口的方法,并且让isRuntime()方法返回true,这样就可以创建动态切入点。,,创建引入,其他类型的通知在方法调用周围的不同连接点被织入。引入则影响整个类。他们通过为被通知的类(advisedclass)增加新的方法和属性来实现。你可以用一个已经存在的类,让它实现另外的接口,维持另外的状态(这也叫做混入mix-in)。Spring的Introductionadvice是一个特殊的advice,它并不使用在PointCut级别上,而是使用于类级别上,当对象发生接口转换时,会通知introductionadvice介入。,,实现IntroductionInterceptor,Spring通过一个特殊的拦截器接口IntroductionInterceptor来实现引入。这个接口添加了一个方法:booleanimplementsInterface(Classintf);如果IntroductionInterceptor实现了指定的接口,那么这个方法返回true。Introductionadvice不能被用于任何切入点,因为它只能作用于类级别上,而不是方法。实现IntroductionInterceptor接口,同时实现你需要引入的接口。例如,有一个遗留的代码,对文件进行数据写入操作。然而在运行过程中,发现经常会有多个用户同
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度房地产交易法律顾问服务合同
- 二零二五年度新能源充电桩建设与运营合同
- 二零二五年度新能源项目合作协议范本
- 加强校园安全管理实施方案
- 2025年低压配电室检修及清扫安全操作规程
- 银孚一级消防工程师课件
- 装配式建筑施工优缺点综合评估报告
- 中国智慧屏行业发展监测及投资战略咨询报告
- 中国LED硅胶行业发展趋势预测调查报告
- 2025-2030年中国单冻鲅鱼片项目投资可行性研究分析报告
- 村子绿化设计方案(3篇)
- 2025浙能集团甘肃有限公司新能源项目招聘22人笔试历年参考题库附带答案详解
- GB/T 45805-2025信控服务机构分类及编码规范
- DB3309-T 112-2024 嵊泗贻贝苗种包装运输通.用技术条件
- 【正版授权】 IEC 60931-2:2025 EN-FR Shunt power capacitors of the non-self-healing type for AC systems having a rated voltage up to and including 1 000 V - Part 2: Ageing test and destru
- 班主任安全管理培训讲座
- 2024年云南省罗平县人民医院公开招聘护理工作人员试题带答案详解
- 2025年农业灌溉站租赁合同范本
- 高新技术产业厂房抵押贷款合同范本
- 冲压工厂批次管理办法
- 【历史 广东卷】2025年广东省高考招生统一考试真题历史试卷(真题+答案)
评论
0/150
提交评论