下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Spring-AOP,Louis Young,功能模块化与面向过程,最早的功能模块化是把某些重复的或功能独立,日志子过程,业务处理过程,日志子过程,某业务处理过程(过程集成),IoC回顾,IoC就是利用容器通过XML配置描述把各种不同功能的模块组合成一个完整的业务逻辑流程. 其核心是:容器与XML描述. 其实现是:通过Java的反射实例化对象,管理对象,访问对象(定位). 其作用是:降低模块间的耦合度,达到模块复用,业务逻辑流程动态化,灵活化,可定制化,可扩展化.,IoC与模块化,日志功能bean,业务处理功能bean,日志功能bean,BeanFactory(功能Bean集成),对模块化的概
2、念抽象-切面,日志模块,业务处理模块,日志模块,一个切面(方面)Aspect,对模块化的概念抽象-连接点,连接点(调用日志模块的地方),连接点(JoinPoint) 程序运行过程中的某个阶段点。,AOP,在前面我们了解的的概念其实就是面向Aspect的.简称AOP. 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。 因为OOP面向的是以数据为中心的对象. AOP面向的是以功能为中心的模块.AOP的实现还是以OOP为手段.,AOP具体实现,AspectJ (TM): 创建于Xerox PARC. 有近十年历史,成熟 缺点:过于复杂;破坏封装;
3、需要专门的Java编译器。 动态AOP: 使用JDK的动态代理API或字节码Bytecode处理技术。 Spring 采用的是动态AOP.,Spring中的AOP实现,Spring AOP用纯Java实现。它不需要专门的编译过程。Spring AOP不需要控制类装载器层次,因此它适用于J2EE web容器或应用服务器。 Spring实现AOP的方法跟其他的框架不同。Spring并不是要尝试提供最完整的AOP实现(尽管Spring AOP有这个能力), 相反的,它其实侧重于提供一种AOP实现和Spring IoC容器的整合,用于帮助解决在企业级开发中的常见问题。 Spring缺省使用J2SE 动
4、态代理(dynamic proxies)来作为AOP的代理。这样任何接口都可以被代理。 Spring也支持使用CGLIB代理. 对于需要代理类而不是代理接口的时候CGLIB代理是很有必要的。,AOP与IoC,Spring IoC容器并不依赖于AOP,这意味着你可以自由选择是否使用AOP. AOP提供强大的中间件解决方案,这使得Spring IoC容器更加完善。,AOP概念(一/二),切面(Aspect): 一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 连接点(Joinpoint): 在程序执行过程中某个特定的点,比如某方法调用的时候
5、或者处理异常的时候。 在Spring AOP中,一个连接点 总是 代表一个方法的执行。 通知(Advice): 在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。 切入点(Pointcut): 匹配连接点(Joinpoint)的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。 切入点表达式如何和连接点匹配是AOP的核心,AOP概念(二/二),引入(Introduction): (也被称为内部类型声明(inter-type declaration)。
6、声明额外的方法或者某个类型的字段。 Spring允许引入新的接口到任何被代理的对象。 目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(advised) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。 AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 织入(Weaving): 把切面(aspect)
7、连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象。 这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。 Spring和其他纯Java AOP框架一样,在运行时完成织入。,AOP的目的,提供功能分离框架(模块化) 主要代码上分离业务逻辑实现与非业务逻辑实现. 可以降低两种代码的耦合性 . 从而达到代码重用和易于维护的目的,AOP与Java代理机制,AOP是一种思想,它和具体的实现技术无关。任何一种符合AOP思想的技术实现,都可以看作是AOP的实现。 JDK 1.3以后,Java提供了动态代理的机制。通过Java的动态代理机制,就可以很容易地实现A
8、OP的思想。实际上Spring的AOP也是建立在Java的代理机制之上的。,Java代理回顾,Proxy InvocationHandler,请参考例子:ProxyDemo 请参考例子:UseProxyClass,例子- Java代理,MyInterface.do(),MyInterfaceImpl,MyHandler.invoke(),Proxy. newProxyInstance,代理对象.do(),例子-代理的核心代码,public class MyHandler implements InvocationHandler private T t; private OtherFunc ot
9、her; public MyHandler(T t,OtherFunc other) this.t=t; this.other=other; public Object invoke(Object proxy, Method method, Object args) throws Throwable System.out.println(我知道马上要被调用的方法是:+method.getName(); other.other(这是其他方法); return method.invoke(t,args); ,连接点,切入点(条件与表达式),引入,通知,目标对象,AOP框架概念示意图,认识Sprin
10、g AOP APIs,Spring AOP API其实把我们上面的思想框架化的一组API,通过这组API我们可以很轻松的解决在企业级开发中的常见问题 :比如常见的事务管理.,Spring AOP的实现关键,产生advice 定义pointcuts 使用ProxyFactoryBean 理解自动代理,通知的生命周期,每个通知都是一个Spring bean。一个通知实例既可以被所有被通知的对象共享,也可以被每个被通知对象独占。 这根据设置类共享(per-class)或基于实例(per-instance)的参数来决定。 类共享通知经常会被用到。它很适合用作通用的通知例如事务advisor。这些adv
11、isor不依赖于代理对象的状态也不会向代理对象添加新的状态;它们仅仅在方法和参数上起作用。 基于实例的通知很适合用作导入器来支持混合类型。在这种情况下,通知向代理对象添加状态。 在同一个AOP代理里混合使用类共享和基于实例的通知是可能的。,Advice的类型,拦截around通知 前置通知 后置通知 异常通知 引入通知,例子-BeforeAdvice,Before通知只在JointPoint前执行, 实现Before通知的类需要实现接口MethodBeforeAdvice,例子-功能bean(1/5),代理的基本实现手段接口 public interface IDAO boolean inse
12、rt(T bean); /* boolean save(T bean); boolean update(T bean); boolean deleteByObject(T bean); */ 功能实现类 public class BookDAO implements IDAO public boolean insert(Books bean) /这里原来是准备写日志 System.out.println(在处理业务逻辑中. + bean); /用线程替代具体的业务处理过程 try Thread.currentThread().sleep(2000); catch (InterruptedExc
13、eption e) e.printStackTrace(); System.out.println(在处理业务逻辑结束 + bean); /这里原来应该有日志代码,而且与log4j耦合 return false; ,请参考例子:AOPBeforeAdvice,例子-切面与advice(2/5),public class LogBeforAdvice implements MethodBeforeAdvice private Logger logger =Logger.getLogger(this.getClass().getName(); public void before(Method m
14、ethod, Object args, Object target) throws Throwable logger.log(Level.INFO, method + 开始被调用于+ new Date(); ,例子-advice部署描述(3/5), db.IDAO logbeforeadvice ,例子-advice调用(4/5),ApplicationContext context = new FileSystemXmlApplicationContext(beans-config.xml); IDAO daoProxy =(IDAO) context.getBean(bookdao); B
15、ooks book=new Books(); book.setId(1); book.setName(战争与和平); book.setAuthor(俄国人); boolean re=daoProxy.insert(book);,例子-体会(5/5),业务逻辑与非业务逻辑的分割 AOP的几个基本概念就是掌握AOP的关键点. SpringAOP是用Proxy实现. 注意泛型的使用.在接口中使用泛型,配置接口的时候不需要指定.,例子-AroundAdvice,Around通知会在JointPoint的前后执行. 需要实现接口MethodInterceptor . 包 org.aopalliance.
16、intercept.MethodInterceptor; public Object invoke(MethodInvocation arg0) throws Throwable 参考提供的例子AOPAllDevice,例子-AfterAdvice,After Returning通知只在JointPoint后执行. 实现After Returning通知的类需要实现接口AfterReturningAdvice. 参考提供的例子AOPAllDevice,例子-ThrowsAdvice,Throw通知只在JointPoint抛出异常时执行. 实现Throw通知的类需要实现接口ThrowsAdvic
17、e. 该接口中没有任意的方法,但必须实现一个函数 afterThrowing(Method, args, target, Throwable subclass) 前面三个参数是可选的 参考提供的例子AOPAllDevice,例子-Introduction,Introduction通知只在JointPoint调用完毕后执行. 实现Introduction通知的类需要实现接口IntroductionAdvisor和接口IntroductionInterceptor。 参考提供的例子AOPIntroduction,Spring里的advisor(Advisor),在Spring里,一个advisor
18、是一个仅仅包含一个通知对象和与之关联的切入点表达式的切面。 除了引入这种特殊形式,任何advisor都可以和任何通知一起工作。 org.springframework.aop.support.DefaultPointcutAdvisor是最常用的advisor类。例如,它可以和: MethodInterceptor,BeforeAdvice 或者 ThrowsAdvice一起使用。 在Spring里有可能在同一个AOP代理里模糊advisor和通知类型。例如,你可以在一个代理配置里使用一个interception环绕通知,一个异常通知和一个前置通知:Spring将负责自动创建所需的拦截器链.,
19、Spring的切入点(Pointcut),Pointcut是Join Point的集合,它是程序中需要注入Advice的位置的集合。 Spring的切入点模型使得切入点可以独立于通知类型进行重用,这就使得针对不同 advice使用相同的pointcut成为可能。 Spring主要提供了3种切入点(Pointcut)的实现: 静态切入点. 动态切入点. 自定义切入点.,静态切入点,静态切入点只限于给定的方法和目标类,而不考虑方法的参数。 Spring在调用静态切入点时只在第一次的时候计算静态切入点的位置,然后把它缓存起来,以后就不需要再进行计算。就是Spring只在第一次调用方法时执行静态切入点
20、:以后每次调用这个方法时就不需要再执行。 使用org. springframework. aop. support. RegexpMethodPointcut 可以实现静态切入点. RegexpMethodPointcut是一个通用的正则表达式切入点,它是通过Jakarta ORO来实现的,需要把jakarta-oro-2.0.8.jar加入到ClassPath中,它的正则表达式语法和Jakarta ORO的正则表达式语法是一样的。,例子-切入点接口(1/5),public interface IFunc void doSomething(String info); void doAnotho
21、er(); void print(String info); void println(String info); 需要在上面函数切入一些功能处理.,请参考例子:AOPStaticPointcut,例子-切入点接口实现(2/5),public class FuncImpl implements IFunc public void doAnothoer() System.out.println(调用do开头的方法 Another); public void doSomething(String info) System.out.println(调用do开头的方法 Something); publ
22、ic void print(String info) System.out.println(调用print开头的方法 print); public void println(String info) System.out.println(调用print开头的方法 println); ,例子-切入点接口实现(3/5),切入的advice的实现 public class UseBeforeAdvice implements MethodBeforeAdvice public void before(Method arg0, Object arg1, Object arg2) throws Thro
23、wable System.out.println(切入的处理调用。); ,例子-切入点接口实现(4/5), .*print.* .*do.* IFunc regExpAdvisor ,例子-思考(5/5),切入点就是是Advice要切入的条件. 体会切入点与连接点的概念. 体会Aspect与Advice的关系,动态切入点,动态切入点与静态切入点的区别是,它不仅限定于给点的方法和类,动态切入点还可以指定方法的参数。 因为参数的变化性,所以动态切入点不能缓存,需要每次调用的时候都进行计算,因此使用动态切入点有很大的性能损耗。 当切入点需要在执行时根据参数值来调用通知时,就需要使用动态切入点。Spr
24、ing提供了一个内建的动态切入点:控制流切入点。此切入点匹配基于当前线程的调用堆栈。开发人员只有在当前线程执行时找到特定的类和特定的方法才返回true。 其实大多数的切入点可以使用静态切入点,所以很少有机会创建动态切入点。,控制流切入点,动态切入点的一个经典Spring实现是是控制流切入点。 控制流切入点是由org.springframework.aop.support.ControlFlowPointcut 类声明的。 在执行时控制流切入点的开销是非常昂贵的,甚至与其它动态切入点比起来也是如此。,例子-动态切入点,参考提供的例子AOPDynamicPointcut,关于切入与织入的深入理解,
25、织入是实现AOP的一个重要机制,织入的实现机制有多种,基本上可以分为两类,静态织入与动态织入。 静态织入是指在业务功能代码中的适当位置,比如某段代码执行前,或执行后,将方面中的编码插入,从而形成混合的编码。方面中的编码在程序运行前,已被内联至业务功能代码中,因此,代码可以被优化,从而使织入产生的开销最小化,最终产生的混合代码,其执行速度接近为使用AOP方式编写的代码。 但是,静态织入无法做到在程序运行时,根据运行上下文动态的决定插入的方面代码,动态织入则可以做到这一点。 动态织入可以在程序运行时,根据上下文决定调用的方面,它们的先后顺序,增加或删除一个方面等。 而根据织入的时间,又可以分为三类
26、,编译时,载入时,运行时。编译时织入可以在编译前进行预处理,将两种代码自动混合,将方面中的代码自动插入到功能模块代码的合适位置处,也可在编译后,对编译后的代码进行操作。载入时织入是在代码载入时,实现代码的织入。运行时织入则在运行时,根据对方法的调用执行适当的方面代码以实现织入。,自定义切入点,因为Spring中的切入点是Java类,而不是语言特性(如AspectJ),因此可以定义自定义切入点。,使用ProxyFactoryBean创建AOP代理,在Spring里创建一个AOP代理的基本方法是使用org.springframework.aop.framework.ProxyFactoryBean
27、。这个类对应用的切入点和通知提供了完整的控制能力(包括它们的应用顺序)。,ProxyFactoryBean类属性(1/2),指定你希望代理的目标对象 指定是否使用CGLIB proxyTargetClass:这个属性为true时,目标类本身被代理而不是目标类的接口。 optimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略。除非完全了解AOP代理如何处理优化,否则不推荐用户使用这个设置。目前这个属性仅用于CGLIB代理;对于JDK动态代理(缺省代理)无效。 frozen:用来控制代理工厂被配置之后,是否还允许修改通知。缺省值为false(即在代理被配置之后,不允许修改代理的配置
28、)。 exposeProxy:决定当前代理是否被保存在一个ThreadLocal中以便被目标对象访问。(目标对象本身可以通过MethodInvocation来访问,因此不需要ThreadLocal。) 如果个目标对象需要获取代理而且exposeProxy属性被设为true,目标对象可以使用AopContext.currentProxy()方法。,ProxyFactoryBean类属性(2/2),aopProxyFactory:使用AopProxyFactory的实现。这提供了一种方法来自定义是否使用动态代理,CGLIB或其它代理策略。 缺省实现将根据情况选择动态代理或者CGLIB。一般情况下应
29、该没有使用这个属性的需要;它是被设计来在Spring 1.1中添加新的代理类型的。 proxyInterfaces:需要代理的接口名的字符串数组。如果没有提供,将为目标类使用一个CGLIB代理 单例:工厂是否应该返回同一个对象,不论方法getObject()被调用的多频繁。多个FactoryBean实现都提供了这个方法。缺省值是true。如果你希望使用有状态的通知-例如,有状态的mixin-可以把单例属性的值设置为false来使用原型通知。,Spring中的自动代理提出的背景,不管是使用Java的动态代理还是使用CGLIB代理,虽然功能很强大,但是对于每一个类,都要在Spring的配置文档中建
30、立相应的代理,如果只是一个很小的应用系统,还看不出来工作量有多大,但对于一个大型的企业应用来说,工作量就太大了,而且重复性的工作很多. Spring提供了一种自动代理的方式,可以减轻这部分工作。,自动代理实现,要使用Spring中的动态代理,org.springframework.aop.framework.autoproxy包是必需的 . Spring提供两种自动代理产生器: BeanNameAutoProxyCreator DefaultAdvisorAutoProxyCreator,例子-缺省自动代理,DefaultAdvisorAutoProxyCreator的实施步骤: 直接去掉 I
31、Func regExpAdvisor 在获取代理的时候,不使用代理bean的名字,而是使用接口实现bean的名字。 请参考提供的例子代码。,请参考例子:AOPAutoProxyDefault,例子-按方法名自动代理(1/4),要自动代理的两个Bean类(这里我们没有采用接口了) public class MyBeanOne public void doMethodOne() System.out.println(Bean-1); public class MyBeanTwo public void doMethodTwo(String info) System.out.println(要打印的
32、信息: +info); ,请参考例子:AOPAutoProxyBeanName,例子-按方法名自动代理(2/4),切入实现 public class MyAroundAdvice implements MethodInterceptor public Object invoke(MethodInvocation invocation) throws Throwable System.out.println(before); Object retVal=ceed(); System.out.println(after); return retVal; ,例子-按方法名
33、自动代理(3/4),自动代理的配置 beanOne beanT* advice ,例子-按方法名自动代理(4/4),调用自动代理的bean public class TestAutoProxy public static void main(String args) ApplicationContext context=new ClassPathXmlApplicationContext(beans-config.xml); MyBeanOne one=(MyBeanOne)context.getBean(beanOne); MyBeanTwo two=(MyBeanTwo)context.g
34、etBean(beanTwo); one.doMethodOne(); two.doMethodTwo(Hello); ,其他代理例子,静态代理例子 动态代理例子 注意通过该例子理解什么是代理. 练习:使用这种代理来实现数据库事务,思考:可以用AOP实现的应用,Authentication 权限 Caching 缓存 Context passing 内容传递 Error handling 错误处理 Lazy loading懒加载 Debugging调试 logging, tracing, profiling and monitoring记录跟踪优化校准 Performance optimization性
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 淀粉基生物降解高分子材料:制备工艺、性能特征与应用前景探究
- 液氮深低温保存对同种带瓣大动脉组织结构影响的深度剖析
- 消费资本化理论驱动下的平台生态系统创新与发展研究
- HR+HER-2-早期乳腺癌复发风险与临床管理专家共识总结2026
- 2026年安徽三线销售返利合同三篇
- 妊娠期胰腺炎的经皮穿刺引流技术
- 妊娠期胰腺炎内镜治疗中的医患沟通要点
- 妊娠期肝内胆汁淤积症胎儿监护的NST应用规范执行
- 妊娠期结核病合并妊娠期早产儿的生长发育促进团队工作计划
- 2026上海中考历史考前提分模拟卷含答案
- 中信建投证券2026届金融科技专场春季校园招聘备考题库含答案详解(基础题)
- 长沙理工大学招聘考试试题
- TSG 92-2026 承压类特种设备安全附件安全技术规程
- 2026年国测模拟测试初中劳动试题
- (正式版)DB37∕T 4976-2025 《河湖生态产品价值核算技术规范》
- 人教版初中物理八年级下册《功和机械能》大单元教学设计
- 企业安全环保管理体系及制度
- JJG196-2023常用玻璃量器检定规程【关键要点与实操解读】
- 装配式住宅建筑检测技术标准JGJ-T485-2019
- 2026大学生国家安全知识竞赛试题及答案
- 冲击地压基础知识课件
评论
0/150
提交评论