1、讲讲使使用用SpringSpringAOPAOP第第1010的的2本讲内容v 从企业应用的思考从企业应用的思考v 如何应对挑战如何应对挑战v 常用设计模式与动态代理常用设计模式与动态代理v 面向方面编程(面向方面编程(AOPAOP)v Spring2.xSpring2.x对对AOPAOP的支持的支持3从企业应用的思考企业应用开发面临的挑战企业应用开发面临的挑战 v 企业应用的开发是企业应用的开发是相当复杂相当复杂的,这种复杂除了表现在的,这种复杂除了表现在技术技术方面方面外,还表现在外,还表现在行业本身行业本身。 v 企业级应用的开发往往需要面对更多的问题企业级应用的开发往往需要面对更多的问题
2、 大量的并发访问大量的并发访问 复杂的环境复杂的环境 网络的不稳定网络的不稳定 还有外部的还有外部的CrackCrack行为等行为等v 因此企业级应用必须提供更好的因此企业级应用必须提供更好的多线程多线程的支持,具备良好的支持,具备良好的的适应性适应性及良好的及良好的安全性安全性等。等。 4从企业应用的思考思考的方面思考的方面v 可扩展性、可伸缩性可扩展性、可伸缩性 一个积极的软件开发者应该正确对待需求的变更。需求的变更表明有市场前景,只有有变化的产品才是有市场的产品。 优秀的企业级应用必须具备良好的可扩展性和可伸缩性。因为良好的可扩展性允许系统动态增加新功能,而不会影响原有的功能。 良好的可
3、扩展性建立在高度的解耦之上。在JEE应用中,大多采用XML文件作为配置文件。使用XML配置文件可以避免修改代码,从而能极好地提高程序的解耦。 5从企业应用的思考思考的方面思考的方面v 快捷、可控的开发快捷、可控的开发 如果没有时间限制,任何一个软件系统在理论上都是可实现的。 但这样的条件不存在,软件系统必须要及时投放市场。对于企业级应用,时间的限制则更加严格。 企业的信息是瞬息万变的,与之对应的系统必须能与时俱进。因而采用新技术的问题,乐于与风险。 因此快捷、可控是企业信息化系统必须面对的挑战。6从企业应用的思考思考的方面思考的方面v 稳定性、高效性稳定性、高效性 企业级应用的一个显著特点:并
4、发访问量大,访问频繁。因此稳定性、高效性是企业级信息化系统必须达到的要求。 企业级应用必须有优秀的性能,如采用缓冲池的技术保存那些创建开销大的对象(典型的应用是数据连接池)、数据缓存。 7从企业应用的思考思考的方面思考的方面v 花费最小化,利益最大化花费最小化,利益最大化永恒的话题永恒的话题 任何一个商业组织都希望尽可能地降低开销。 对开发者而言,降低开销主要是如何使在开发上的投资更有保值效果。即开发的软件系统具有很好的复用性。 在良好的JEE架构设计中,复用是一个永恒的追求目标。架构设计师希望系统中大部分的组件可以复用,甚至能让系统的整个层可以复用。对于采用DAO模式的系统架构,如果数据库不
5、发生大的改变,整个DAO层都不需要变化。8本讲内容v 从企业应用的思考从企业应用的思考v 如何应对挑战如何应对挑战v 常用设计模式与动态代理常用设计模式与动态代理v 面向方面编程(面向方面编程(AOPAOP)v Spring2.xSpring2.x对对AOPAOP的支持的支持9从企业应用的思考如何应对挑战如何应对挑战v 使用使用建模工具建模工具 建模工具不一定是ROSE等,可以是简单的手画草图。当然,借助于专业的建模工具可以更好地确定系统模型。 任何语言的描述都是很空洞,而且具有很大的歧义性。使用图形则更加直观,而且意义更加明确。 关于建模工具,推荐采用统一建模语言:UML。但UML的使用也需
6、要掌握分寸。在软件开发人员内部使用时,尽可能使用规范的UML;但用于与行业专家沟通时,要辅助文字说明。10从企业应用的思考如何应对挑战如何应对挑战v利用利用优秀的框架优秀的框架 使用框架可以大大提高系统的开发效率。除非开发一个非常小的系统,而且是开发后无须修改的系统,才可以完全抛弃框架。好处:1提高生产效率2具有更稳定、更优秀的性能 如果不使用已有的框架,系统开发者将面临着需要自己完成所有的底层部分。除非开发者丝毫不遵守软件复用的原则,总是重复书写相同代码。3更好的保值性11从企业应用的思考如何应对挑战如何应对挑战v选择性地扩展选择性地扩展 软件的需求千变万化,任何框架不可能总是那么完美,难免
7、需要扩展现有的框架。 对已有的框架进行扩展,则可最大限度地利用已有的框架,但是不要盲目扩展现有框架,因为新增的部分有时会引入新的风险。尽量利用已有组件,除非无法使用已有框架时,才考虑选择性地扩展。12从企业应用的思考如何应对挑战如何应对挑战v使用使用代码生成器代码生成器 使用代码生成器可以自动生成部分程序。使用代码生成器可以自动生成部分程序。 13本讲内容v 从企业应用的思考从企业应用的思考v 如何应对挑战如何应对挑战v 常用设计模式与动态代理常用设计模式与动态代理v 面向方面编程(面向方面编程(AOPAOP)v Spring2.xSpring2.x对对AOPAOP的支持的支持14从企业应用的
8、思考常用的设计模式及应用常用的设计模式及应用v单态模式单态模式的使用的使用 在任何不需要重复生成Java实例的场景中,都应该考虑使用单态模式。 使用单态模式可以保证系统无须生成多个Java实例,从而减少内存占用率,也降低JVM(Java虚拟机)进行垃圾回收的开销。 单态模式通常有如下两个使用场景: 1.1.工厂模式中的工厂模式中的工厂(工厂不要重复生产产工厂(工厂不要重复生产产品)品)。 2.2.使用服务定位器模式时的使用服务定位器模式时的服务定位器(尽量服务定位器(尽量找)找)。15从企业应用的思考常用的设计模式及应用常用的设计模式及应用v代理模式代理模式的使用的使用 传统的代理模式主要用于
9、用简单对象来代替复杂的对象,如果创建一个对象所需的时间比较长,且计算资源相当昂贵,可以采用一个相对简单的对象来代替它。代理模式可将创建过程推迟到真正需要该对象时完成,一旦整个对象创建成功,对代理的方法调用将变成对实际对象的方法调用。 16从企业应用的思考常用的设计模式及应用常用的设计模式及应用v代理模式代理模式的使用的使用 Java EE中的代理模式通常是采用功能更强大的对象来代替目标对象。 例如,对于普通的业务逻辑组件,其方法都应该有事务性,但这种开始事务和结束事务都是通用步骤。 因此原始业务逻辑对象的方法可以无须事务操作,而是由系统生成动态代理,调用实际的目标方法并负责事务操作。17从企业
10、应用的思考v对象由工厂产生。对象由工厂产生。v工厂作为工厂作为代理处理器代理处理器,对产生的对象,对产生的对象增加增加事务处事务处理代码或安全处理代码。理代码或安全处理代码。v主要是对对象中的主要是对对象中的方法增加事务处理方法增加事务处理代码。代码。v可以在处理器中硬编码,对方法增加代码。可以在处理器中硬编码,对方法增加代码。v通用的通用的代理处理器代理处理器,该处理器并不需要与任何特,该处理器并不需要与任何特定的目标对象耦合。定的目标对象耦合。 v为了该代理处理器有更好的适应性,系统可以将为了该代理处理器有更好的适应性,系统可以将需要增加事务操作的需要增加事务操作的方法方法以以XML文件配
11、置,而该文件配置,而该代理处理器代理处理器负责解析负责解析XML文档,根据配置决定对文档,根据配置决定对哪个方法增加事务处理。哪个方法增加事务处理。18从企业应用的思考v 动态代理动态代理 在运行时,能够动态实现指定接口的机制,从而生成新的类。 动态代理是JDK1.3引入的。 开发者需要借助于java.lang.reflect.Proxy类来启用代理。 为某对象创建代理后,所有对被代理对象的请求都经过代理的处理,即代理拦截了客户的请求。 为创建动态代理,开发者需要借助Proxy提供的newProxyInstance()方法,并将定义代理类的类装载器、代理实现的接口集合、InvocationHa
12、ndle传入这一静态方法。19本讲内容v 从企业应用的思考从企业应用的思考v 如何应对挑战如何应对挑战v 常用设计模式与动态代理常用设计模式与动态代理v 面向方面编程(面向方面编程(AOPAOP)v Spring2.xSpring2.x对对AOPAOP的支持的支持20AOP概述v AOPAOP(Aspect Oriented ProgrammingAspect Oriented Programming)的背景知识)的背景知识 为满足整个企业应用某方面的需求,开发者为满足整个企业应用某方面的需求,开发者( (架构师架构师) )需要整理出系统的关注点,如下图形象地描述了关注点。需要整理出系统的关注
13、点,如下图形象地描述了关注点。21比如:事务管理、安全性管理、应用的业务逻辑都是应用需要重点解决的问题。被作为关注点看待。整个系统由大量的关注点构成。22AOP概述关注点分类关注点分类v 大体而言,关注点分为两类:大体而言,关注点分为两类:v 核心关注点主要关注系统的业务逻辑;核心关注点主要关注系统的业务逻辑;v 横切关注点主要关注系统级的服务,供业务逻辑使用。横切关注点主要关注系统级的服务,供业务逻辑使用。关注点核心关注点横切关注点23AOP概述v 现实状态现实状态 业务逻辑中,到处都涉及横切关注点。因此对各个已经实现的模块(业务逻辑)而言,都有大量的横切关注点实现。v 新的方案新的方案 业
14、务逻辑用OO技术实现; 横切关注点用AOP技术实现; 横切关注点是系统级服务,对大部分应用是常见的,容易抽象出来,并加以实现。24AOP概述v 实现实现AOPAOP的总体模式的总体模式 OO技术将应用中的核心关注点分解成由层次(继承)结构组成的领域对象集合。 AOP将应用中的横切关注点分解成由切面(Aspect)组成的生态子系统。 它们被分别实现,互为补充,使得应用的开发变得简单、可维护性得到增强。25AOP概述v 实现实现AOPAOP的总体模式的总体模式 为实现单个横切关注点,开发者需要采用若干切面满足它。比如为实现安全性控制横切关注点,开发者需要提供用户论证切面、用户授权切面。26AOP的
15、基本概念v 各种各种AOPAOP实现切面实现切面的技术、框架、机制、手段可能不同,的技术、框架、机制、手段可能不同,但是但是AOPAOP技术的基本概念是相同的。包括以下个术语技术的基本概念是相同的。包括以下个术语: : 连接点(join point) 切入点(cutpoint) 装备(advice) 引入(introduction) 目标对象(target object) 织入(weaving)和 切面(Aspect)。27AOP的基本概念v 连接点连接点(Joinpoint)(Joinpoint) 连接点指应用(目标对象)执行的某个点,如执行到某个方法、访问到某个成员变量、抛出某异常、装载某
16、个类。 通常用连接点的强弱来衡量AOP实现的强弱。Aspect5实现的连接点类型非常多,Spring AOP仅支持方法级连接点。28AOP概念v 切入点(切入点(pointcutpointcut) 通过切入点能够声明、集结连接点。 通常装备与切入点关联在一起,一旦某连接点被触发,则会立即执行相应的装备。开发者借助于pointcut表达语言来完成pointcut的指定工作。29AOP概念v 装备装备(Advice)(Advice) 装备指切面(aspect)在特定连接点所采取的动作。特定连接点由切入点(pointcut)指定。 主要的装备类型包括:Before、 AfterReturning、A
17、fterThrowing、 After 、Around。 Before装备能够在特定连接点被触发前执行,如方法执行前执行的装备。其它类似。30AOP概念v 引入(引入(introducionintroducion) 引入也称为inter-type声明(AspectJ5)。将新的接口、方法、成员变量动态引入到目标类、接口或切面中。v 目标对象(目标对象(target Objecttarget Object) 被若干切面(aspect)装配过的对象,也被称为被装备的对象。31AOP概念v 织入(织入(weavingweaving) 将切面(Aspect)与目标对象组装在一起的过程称为织入。通过织入
18、创建一个被装备的对象。 织入时机有编译期、装载期、运行期。 不同的AOP实现支持不同织入时机。如Spring AOP支持运行期织入;AspectJ5支持编译期和类装载期(Load-Time)织入。32AOP概念v 切面切面(aspect)(aspect) 与OOP中对象的概念一样,是AOP中的核心概念。 切面将pointcut、装备、引入、目标对象等信息集结在一起,从而定义相应的织入规则,这样一个整体称为切面(aspect)。33Spring对AOP的支持vAOPAOP是一种流行的编程模型;是一种流行的编程模型;vAOPAOP的编程思想与的编程思想与OOPOOP不同,是对不同,是对OOPOOP
19、的一种强有力的的一种强有力的补充;补充;v通过通过AOPAOP,能,能更好更好地实现地实现模块化结构模块化结构,或者能,或者能动态地动态地为系统增加新功能为系统增加新功能而不影响原系统的结构而不影响原系统的结构34Spring AOPv 概述概述 AOP AOP 允许开发者允许开发者动态地修改动态地修改OOPOOP定义的静态模型定义的静态模型,即,即不用修改原来的不用修改原来的OOOO模型,甚至可以不修改模型,甚至可以不修改OOOO代码本身,即代码本身,即可完成对横切面问题的解决。可完成对横切面问题的解决。 比如,将系统中处理日志、安全性、事务及其他企业比如,将系统中处理日志、安全性、事务及其
20、他企业级服务集中放置在一个地方。因此级服务集中放置在一个地方。因此AOPAOP使得使得OOPOOP中的重复代中的重复代码能够大范围减少。码能够大范围减少。35Spring框架介绍v SpringSpring就是一个实现了就是一个实现了AOPAOP功能的功能的IOCIOC容器容器36Spring AOPv Sping AOPSping AOP基于基于IoCIoC,是对,是对OOPOOP的有益补充的有益补充. .v Sping AOPSping AOP将应用系统分为两部分,将应用系统分为两部分,核心业务逻辑核心业务逻辑及及横向横向的通用逻辑,的通用逻辑,即方面即方面(Aspect)(Aspect)
21、。比如大型应用中涉及的持。比如大型应用中涉及的持久化管理、事务管理、安全管理、日志管理和调试管理。久化管理、事务管理、安全管理、日志管理和调试管理。v 使用使用AOPAOP可以将处理可以将处理AspectAspect的代码注入主程序,的代码注入主程序,AOPAOP可以防可以防止代码混乱。止代码混乱。37Spring对AOP的支持vSpringSpring的的AOPAOP模块实现了模块实现了AOPAOP联盟定义的联盟定义的AOPAOP接口的实现;接口的实现;v利用利用SpringSpring提供的提供的AOPAOP,可以,可以简化代码逻辑简化代码逻辑,分离应用程,分离应用程序的关注点;序的关注点
22、;vSpringSpring提供的提供的许多低层服务许多低层服务(如对声明式事务的管理的(如对声明式事务的管理的支持)是基于支持)是基于AOPAOP实现的;实现的;v与其它与其它AOPAOP框架不同,框架不同,SpringSpring的思想仍然建立在的思想仍然建立在IoCIoC之上,之上,即即AOPAOP本身也是以本身也是以BeanBean的方式在的方式在SpringSpring的的IoCIoC容器中装配容器中装配起来的。起来的。38Spring的设计思想SpringSpring的设计思想的设计思想v工厂模式和工厂模式和更好的更好的singletonsingleton(单例)解决方案(单例)解
23、决方案 使用工厂模式创建对象比用new 更加容易,因为工厂向客户端隐藏了创建对象的复杂细节; 可以使用Spring提供的工厂类,也可以自己编写工厂类并纳入容器统一管理。 单一实例的对象,其生命周期贯穿整个应用程序。 如采用singleton模式,必须为每个单实例实现复杂的singleton模式; Spring实现了更容易的管理方法,将单实例纳入Spring的IoC容器,由IoC容器保证对象的单实例39Spring AOP的基本概念v SpringSpring使用使用动态代理动态代理实现实现AOPAOP技术。技术。实例HibernateDaoSupport类v DAODAO(如(如UserDAO
24、UserDAO)通常继承)通常继承HibernateDaoSupportHibernateDaoSupport类类 这样的DAO具有Spring封装Hibernate操作数据库的完全功能(自动生成基本CURD操作的代码)。 继承的目的是让Spring管理事务并且使DAO具有面向接口编程的特点 而且在Spring的管理下,数据库连接的打开和关闭,事务的处理也都变成自动化了。40实例HibernateDaoSupport类v HibernateDaoSupport HibernateDaoSupport提供了基于提供了基于AOPAOP的自动事的自动事务处理,程序员完全可以不用理会事务的开始与务处理
25、,程序员完全可以不用理会事务的开始与提交。提交。v在使用在使用JDBCJDBC的一个的一个ConnectionConnection对象中使用一个事对象中使用一个事务时,在务时,在HibernateHibernate中对应的事务要关联一个中对应的事务要关联一个SessionFactorySessionFactory。v然而这个然而这个SessionFactorySessionFactory却没有在却没有在DAODAO中体现。中体现。41实例HibernateDaoSupport类v原因是原因是HibernateDaoSupportHibernateDaoSupport类做了封装,它用类做了封装,
26、它用一个一个setSessionFactorysetSessionFactory方法将方法将SessionFactorySessionFactory进行注入。进行注入。42实例HibernateDaoSupport类v所以继承自所以继承自HibernateDaoSupportHibernateDaoSupport类的类的DAODAO都会具都会具有有SessionFactorySessionFactory的属性,从而可以通过的属性,从而可以通过SessionFactorySessionFactory创建创建SessionSession实例操作数据库。实例操作数据库。43实例HibernateDa
27、oSupport类v虽然有虽然有setset方法,但在哪注入的呢?当然是方法,但在哪注入的呢?当然是IoCIoC容容器根据器根据applicationContext.xmlapplicationContext.xml注入。注入。. bean id=class=com.dao.impl.UserDAOImplproperty name=44实例HibernateDaoSupport类vIoCIoC容器自动将创建的容器自动将创建的DAODAO注入了注入了sessionFactorysessionFactory的对象,所以的对象,所以DAODAO对象就具有了通过对象就具有了通过HibernateHi
28、bernate操操作数据库的功能。作数据库的功能。45实例HibernateDaoSupport类v另外,要使用另外,要使用hibernatehibernate的模板必须继承的模板必须继承 HibernateDaoSupport HibernateDaoSupport 这个类。这个类。46 结束语v 终终v实验报告格式实验报告格式4748AOP概念v 装备的类型装备的类型 Before装备即在执行目标操作(如调用某方法、读取或设置变量取值)之前执行的装备。49AOP概念实例实例v 在某项目中提供了在某项目中提供了test.DisPersonInfo1.javatest.DisPersonInf
29、o1.java类,暴露了类,暴露了两个两个compute()compute()方法。方法。50public class DisPersonInfo1 private static final Log log=LogFactory.getLog(DisPersonInfo1.class);public static void compute(String person) log.info(person); public static void compute(String person,int age) log.info(person+ 已经已经+age+岁了岁了!); 51public cla
30、ss MainTest private static final Log log=LogFactory.getLog(MainTest.class); public static void main(String args) log.info(MainTest main(); DisPersonIpute(Picart); DisPersonIpute(Picart,30); 522008-10-20 22:01:43 MainTest main信息信息: MainTest main()2008-10-20 22:01:43 DisPersonInfo1 compute信息信息: Picart
31、2008-10-20 22:01:43 DisPersonInfo1 compute信息信息: Picart已经已经30岁了岁了!53/一个AspectJ5切面实现 AspectJAop.aj(可以是.java)public aspect AspectJAop public aspect AspectJAop private static final Log private static final Log log=LogFactory.getLog(AspectJAop.class);log=LogFactory.getLog(AspectJAop.class); pointcut xx()
32、 pointcut xx() :execution( :execution(* * DisPersonIpute(.); DisPersonIpute(.); before:xx() before:xx() log.info( log.info(“AspectJAop BeforeAspectJAop Before”);); 54关于该切面实现v AspectJ5AspectJ5的切入点的切入点pointcutpointcut也是也是beanbean对象。对象。v 通过通过pointcutpointcut关键字定义了名为关键字定义了名为xx()xx()的的pointcutpointcut;v
33、xx()pointcutxx()pointcut通过关键字通过关键字executionexecution集结了相应的连接点集结了相应的连接点(join point) (join point) ,即执行,即执行DisPersonInfo1DisPersonInfo1的所有的所有compute()compute()方方法。法。v 通过通过beforebefore关键字引用了关键字引用了xx()pointcutxx()pointcut;说明何时装备该切;说明何时装备该切入点。入点。55关于该切面实现v executionexecution是是AspectJ5AspectJ5中中pointcutpoi
34、ntcut表达语言中的一个关键表达语言中的一个关键字,用来集结方法执行(调用)。字,用来集结方法执行(调用)。Execution(Execution(可见性模式可见性模式( (可选可选): ): 指定目标方法的可见性指定目标方法的可见性( (P)P);返回类型模式返回类型模式( (必须必须) ):目标方法的返回类型:目标方法的返回类型; ;声明类型模式声明类型模式( (可选可选) ):即:即javajava包包; ;方法名模式方法名模式( (参数模式参数模式)()(必须必须) ),指定目标操作的方法名,指定目标操作的方法名异常模式异常模式( (可选可选):):说明目标方法的方法签名中是否指定异
35、常说明目标方法的方法签名中是否指定异常) )Execution(public * test.service.*(.)56关于该切面实现v 该该aspect AspectJAopaspect AspectJAop的使用及效果的使用及效果 通过java jar aspectj-1.5.2a.jar安装AspectJ 5。 将包aspectjrt.jar添加到环境变量中。 用安装目录下的bin中的ajc批处理命令静态织入上述切面,并运行MainTest应用。 Ajc testAspectJAop.aj test DisPersonInfo1.java testMainTest.java java t
36、est.MainTest57关于该切面实现v 效果效果INFO 2007-06-09 09:00:12,203 test.MainTestMainTest.main()INFO 2007-06-09 09:00:12,218 test.AspectJAop AspectJAop BeforeINFO 2007-06-09 09:00:12,218 testDisPersonInfoPicartINFO 2007-06-09 09:00:12,218 test.AspectJAop AspectJAop BeforeINFO 2007-06-09 09:00:12,218 testDisPersonInfoPicart 已经已经30岁了。岁了。