首页 spring中文教程(spring开发指南)_Final

spring中文教程(spring开发指南)_Final

举报
开通vip

spring中文教程(spring开发指南)_FinalSpring开发指南4.doc OpenDoc Series’ Spring 开发指南 V1.6 作者:夏昕 xiaxin(at)gmail.com So many open source projects. Why not Open your Documents?  SpringFrameW ork Developer’s Guide Version 0.6 文档说明 参与人员: 作者 联络 夏昕 xiaxin(at)gmail.com (at) 为 email @ 符号 发布记录 版本 日期 作者 说明 0....

spring中文教程(spring开发指南)_Final
Spring开发指南4.doc OpenDoc Series’ Spring 开发指南 V1.6 作者:夏昕 xiaxin(at)gmail.com So many open source projects. Why not Open your Documents?  SpringFrameW ork Developer’s Guide Version 0.6 文档说明 参与人员: 作者 联络 夏昕 xiaxin(at)gmail.com (at) 为 email @ 符号 发布记录 版本 日期 作者 说明 0.5 2004.6.1 夏昕 第一预览版 0.6 2004.9.1 夏昕 补充“持久层”内容。 OpenDoc 版权说明 本文档版权归原作者所有。 在免费、且无任何附加条件的前提下,可在网络媒体中自由传播。 如需部分或者全文引用,请事先征求作者意见。 如果本文对您有些许帮助, 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 达谢意的最好方式,是将您发现的问题和文档改进意见及时反馈给 作者。当然,倘若有时间和能力,能为技术群体无偿贡献自己的所学为最好的回馈。 另外,笔者近来试图就日本、印度的软件开发模式进行一些调研。如果诸位可以赠阅日本、印度 软件研发过程中的需求、 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 文档以供研究,感激不尽! September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Spring 开发指南 前言 2003 年年初,笔者在国外工作。其时,一位与笔者私交甚好的印度同事 Paradeep 从 公司离职去斯坦福深造,临走送给笔者一本他最钟爱的书籍作为纪念。 工作间隙,时常见到他摩娑此书,摇头不止(印度人习惯和中国人相反,摇头代表肯定、 赞同,相当于与中国人点头。笔者刚开始与印度同僚共事之时,每每组织项目会议,一屋子 人频频摇头,让笔者倍感压力……)。 下班后,带着好友离职的失落,笔者夹着这本书走在回家的路上,恰巧路过东海岸,天 色依然明朗,随意坐上了海边一家酒吧的露天吧台,要了杯啤酒,随手翻弄着书的扉页,不 经意看见书中遍布的钢笔勾画的线条。 “呵呵,Paradeep 这家伙,还真把这本书当回事啊”,一边笑着,一边摊开了此书, 想看看到底是怎样的书让这样一个聪明老练的同事如此欣赏。 从此开始,这本书伴随笔者度过了整整一个月的业余时间…….. 这本书,也就是出自 Rod Johnson 的: 《Expert One-on-One J2EE Design and Development》 此书已经由电子工业出版社出版,译版名为《J2EE 设计开发编程指南》。 半年后,一个新的 Java Framework 发布,同样出自 Rod Johnson 的手笔,这自然 引起了笔者极大的兴趣,这就是 SpringFramework。 SpringFramework 实 际 上 是 Expert One-on-One J2EE Design and Development 一书中所阐述的设计思想的具体实现。在 One-on-One 一书中,Rod Johnson 倡导 J2EE 实用主义的设计思想,并随书提供了一个初步的开发框架实现 (interface21 开发包)。而 SpringFramework 正是这一思想的更全面和具体的体现。 Rod Johnson 在 interface21 开发包的基础之上,进行了进一步的改造和扩充,使其发展 为一个更加开放、清晰、全面、高效的开发框架。 本文正是针对 SpringFramework 的开发指南,讲述了 SpringFramework 的设计思 想以及在开发中的实际使用。同时穿插了一些笔者在项目实作中的经验所得。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Spring 初探....................................................................................................................... 5 准备工作 .......................................................................................................................... 5 构建 Spring 基础代码..................................................................................................... 6 Spring 基础语义............................................................................................................ 12 Dependency Injection............................................................................................. 12 依赖注入的几种实现类型 ........................................................................................ 14 Type1 接口注入................................................................................................. 15 Type2 构造子注入............................................................................................. 15 Type3 设值注入................................................................................................. 15 几种依赖注入模式的对比总结 ............................................................................ 16 Spring Bean 封装机制............................................................................................... 17 Bean Wrapper ........................................................................................................ 17 Bean Factory .......................................................................................................... 18 ApplicationContext ............................................................................................. 21 Web Context........................................................................................................... 26 Spring 高级特性............................................................................................................ 27 Web 应用与 MVC ......................................................................................................... 27 Spring MVC ............................................................................................................. 28 Spring MVC 指南.............................................................................................. 28 基于模板的 Web 表示层技术.............................................................................. 42 Web 应用中模板技术与 JSP 技术的对比........................................................ 47 输入验证与数据绑定 ............................................................................................ 49 异常处理 ................................................................................................................ 60 国际化支持 ............................................................................................................ 62 数据持久层 .................................................................................................................... 66 事务管理 .................................................................................................................... 66 持久层封装 ................................................................................................................ 70 JDBC ...................................................................................................................... 70 Hibernate in Spring.......................................................................................... 78 ibatis in Spring .................................................................................................. 85 以下内容待整理后发布................................................................................................. 88 远程调用 ........................................................................................................................ 88 AOP ................................................................................................................................ 88 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Spring 初探 开始 Spring 研究之前,先让我们来看一个 1 分钟上手 教程 人力资源管理pdf成真迷上我教程下载西门子数控教程protel99se入门教程fi6130z安装使用教程 。 Quick Start! 准备工作 ￘ 下载 SpringFramework 的最新版本,并解压缩到指定目录。 ￘ 在 IDE 中新建一个项目,并将 Spring.jar 将其相关类库加入项目。 笔者所用 IDE 为 Eclipse,类库配置如下: ￘ Spring 采用 Apache common_logging,并结合 Apache log4j 作为日志输出组件。为了在 调试过程中能观察到 Spring 的日志输出,在 CLASSPATH 中新建 log4j.properties 配置文件, 内容如下: ￘ log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%c{1} - %m%n 配置完成后,项目结构如下图所示: September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 构建 Spring 基础代码 示例基础代码包括: 1. Action 接口: Action 接口定义了一个 execute 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 ,在我们示例中,不同的 Action 实现提供了各自的 execute 方法,以完成目标逻辑。 public interface Action { public String execute(String str); } 2. Action 接口的两个实现 UpperAction、LowerAction public class UpperAction implements Action { private String message; public String getMessage() { return message; } public void setMessage(String string) { message = string; } public String execute(String str) { return (getMessage() + str).toUpperCase(); } } UpperAction将其message属性与输入字符串相连接,并返回其大写形式。 public class LowerAction implements Action { private String message; September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 public String getMessage() { return message; } public void setMessage(String string) { message = string; } public String execute(String str) { return (getMessage()+str).toLowerCase(); } } LowerAction将其message属性与输入字符串相连接,并返回其小写形式。 3. Spring 配置文件(bean.xml) Spring Quick Start HeLLo (请确保配置bean.xml位于工作路径之下,注意工作路径并不等同于CLASSPATH ,eclipse 的默认工作路径为项目根路径,也就是.project文件所在的目录,而默认输出目录/bin是项目 CLASSPATH的一部分,并非工作路径。) 4. 测试代码 public void testQuickStart() { ApplicationContext ctx=new FileSystemXmlApplicationContext("bean.xml"); Action action = (Action) ctx.getBean("TheAction"); System.out.println(action.execute("Rod Johnson")); } 可以看到,上面的测试代码中,我们根据"bean.xml"创建了一个ApplicationContext实 例,并从此实例中获取我们所需的Action实现。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 运行测试代码,我们看到控制台输出: …… HELLO ROD JOHNSON 我们将bean.xml中的配置稍加修改: 再次运行测试代码,看到: …… hello rod johnson 示例完成! 很简单的示例,的确很简单,甚至简单到了不够真实。 不过,不知大家从这个最简单的例子中看出了什么? 真的只是打印输出了两行不痛不痒的问候语? 仔细观察一下上面的代码,可以看到: 1. 我们的所有程序代码中(除测试代码之外),并没有出现Spring中的任何组件。 2. UpperAction和LowerAction的Message属性均由Spring通过读取配置文件(bean.xml)动 态设置。 3. 客户代码(这里就是我们的测试代码)仅仅面向接口编程,而无需知道实现类的具体名称。同时, 我们可以很简单的通过修改配置文件来切换具体的底层实现类。 上面所说的这些,对于我们的实际开发有何帮助? ￘ 首先,我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring中脱离,甚 至不需要任何修改(这在基于EJB框架实现的应用中是难以想象的)。 ￘ 其次,组件间的依赖关系减少,极大改善了代码的可重用性。 Spring的依赖注入机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以 指定,从而在相当程度上降低了组件之间的耦合。 上面的例子中,我们通过Spring,在运行期动态将字符串 “HeLLo” 注入到Action实现类的 Message属性中。 现在假设我们回到传统的实现模式,应该如何处理? 一般的处理办法也就是编写一个Helper类(辅助类),完成配置文件读写功能,然后在各个 Action的构造函数中,调用这个Helper类设置message属性值。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 此时,我们的组件就与这个Helper类库建立了依赖关系,之后我们需要在其他系统中重用这个 组件的话,也必须连同这个Helper类库一并移植。实际开发中,依赖关系往往并非如此简单, 组件与项目基层代码之间复杂的关联,使得组件重用性大大下降。 Spring通过依赖注入模式,将依赖关系从编码中脱离出来,从而大大降低了组件之间的耦合, 实现了组件真正意义上的即插即用。这也是Spring最具价值的特性之一。 ￘ 面向接口编程。 诚然,即使没有Spring,实现面向接口的设计也不困难。Spring对于面向接口设计的意义,在 于它为面向接口编程提供了一个更加自然的平台。基于Spring开发,程序员会自然而然倾向于 使用接口来定义不同层次之间的关联关系,这种自发的倾向性,来自于Spring所提供的简单舒 适的依赖注入实现。Spring使得接口的定义和使用不再像传统编码过程中那么繁琐(传统编码 过程中,引入一个接口,往往也意味着同时要引入一个Factory类,也许还有一个额外的配置文 件及其读写代码)。 既然Spring给我们带来了如此这般的好处,那么,反过来,让我们试想一下,如果不使用Spring框 架,回到我们传统的编码模式(也许正是目前的编码模式),情况会是怎样? 对于上例而言,我们需要怎样才能实现相同的功能? 上面的Action接口及其两个实现类UpperAction和LowerAction都与Spring无关,可以保留。而调 用Action的测试代码,如果要实现同样的功能,应该如何编写? 首先,我们必须编写一个配置文件读取类,以实现Message属性的可配置化。 其次,得有一个Factory模式的实现,并结合配置文件的读写完成Action的动态加载。 于是,我们实现了一个ActionFactory来实现这个功能: public class ActionFactory{ public static Action getAction(String actionName){ Properties pro = new Properties(); try { pro.load(new FileInputStream("config.properties")); String actionImplName = (String)pro.get(actionName); String actionMessage = (String)pro.get(actionName+"_msg"); Object obj = Class.forName(actionImplName).newInstance(); //BeanUtils是Apache Commons BeanUtils提供的辅助类 BeanUtils.setProperty(obj,"message",actionMessage); September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 return (Action)obj; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } } 配置文件则采用最简单的properties文件形式: TheAction=net.xiaxin.spring.qs.UpperAction TheAction_msg=HeLLo 测试代码对应更改为: public void testFactory(){ Action action = ActionFactory.getAction("TheAction"); System.out.println(action.execute("Rod Johnson")); } 且不论实现质量的好坏,总之通过上面新增的20来行代码,我们实现了类似的功能(如果不引入 BeanUtils,而采用手工编写Reflection代码完成属性设置的话,显然代码将远远不止20行)。 好吧,现在有个新需求,这个ActionFactory每次都新建一个类的实例,这对系统性能不利,考虑 到我们的两个Action都是线程安全的,修改一下ActionFactory,保持系统中只有一个Action实例供其 他线程调用。 另外Action对象创建后,需要做一些初始化工作。修改一下ActionFactory,使其在创建Action实 例之后,随即就调用Action.init方法执行初始化。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 嗯,好像每次创建Action对象的时就做初始化工作消耗了很多无谓资源,来个Lazy Loading吧, 只有Action实例被实际调用的时候再做初始化。 差不多了,Action的处理就这样吧。下面我们来看看另外一个Factory。 …… 往往这些系统开发中最常见的需求,会导致我们的代码迅速膨胀。纵使苦心经营,往往也未必能得 全功。 而Spring的出现,则大大缓解了这样的窘境。通过对编码中常见问题的分解和抽象,Spring提供了 一套成熟而全面的基础框架。随着本篇的进展,大家可以看到,上面这些开发中常见的问题在Spring框 架中都提供了统一、妥善的处理机制,这为烦杂的应用开发提供了相当有力的支持。 这里暂且抛开Spring Framework在设计上相当出彩的表现不谈。站在应用开发的实际角度来说, 其最大的优势在于:Spring是一个从实际项目开发经验中抽取的,可高度重用的应用框架。认识到这 一点非常重要。 Spring Framework中目前最引人注目的,也就是名为控制反转(IOC =Inverse Of Control) 或者依赖注入(DI =Dependence Injection)的设计思想,这的确是相当优秀的设计理念,但是, 光一个单纯的设计模式并不能使得Spring如此成功,而Spring最成功的地方也并不仅仅在于采用了 IOC/DI的设计。我们前面示例中的ActionFactory,勉强也可算做是一个IOC/DI设计的实现,但又如 何? 可能相关技术媒体和不明就里的技术追随者对于DI/IOC容器的过分炒作,在某种程度上误导了初学 者的视线。“控制反转”,这显然不是一个能望文知意的好名称;“依赖注入”,也好不到哪里去,也正因 为这样,不少初学者都将Spring和生涩的所谓“控制反转”和“依赖注入”看作一个懵懂的高级概念而 供上了神龛。 而实际上,Spring是笔者所见过的,最具实际意义的Java开发框架。它绝非一个高级概念玩具,而 是一个切实的,能实实在在帮助我们改善系统设计的好帮手。 首先,Spring涵盖了应用系统开发所涉及的大多数技术范畴,包括MVC、ORM以及Remote Interface等,这些技术往往贯穿了大多数应用系统的开发过程。Spring从开发者的角度对这些技术内 容进行了进一步的封装和抽象,使得应用开发更为简便。在笔者的开发工作中,借助Spring提供的丰富 类库,相对传统开发模式,大大节省了编码量(平均1/3强,对于ORM和Remote层也许更多)。 其次,Spring并非一个强制性框架,它提供了很多独立的组件可供选择。如笔者在一些项目中,就 仅引用了Spring的ORM模板机制对数据存取层进行处理,并取得了相当理想的效果。 评定一个框架是否优良的条件固然有很多种,但是笔者始终认为,对于应用系统开发而言,我们面 临着来自诸多方面的压力,此时,最能提高生产力的技术,也就是最有价值的技术。很高兴,Spring让 笔者找到了这样的感觉。 笔者对Rod Johnson最为钦佩的,并不是他用了IOC或者DI,而是他对J2EE应用开发的透彻的理 解。 他真的明白开发人员需要什么。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Spring 基础语义 Dependency Injection 何谓控制反转(IoC = Inversion of Control),何谓依赖注入(DI = Dependency Injection)? 对于初次接触这些概念的初学者,不免会一头雾水。正如笔者第一次看到这些名词一样,一阵窘迫…… IT 界不亏是哄抢眼球的行业,每个新出现的语汇都如此迷离。好在我们也同时拥有 Internet 这个最 广博的信息来源。 IoC,用白话来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也 就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。 正在业界为 IoC 争吵不休时,大师级人物 Martin Fowler 也站出来发话,以一篇经典文章《Inversion of Control Containers and the Dependency Injection pattern》为 IoC 正名,至此,IoC 又获得了 一个新的名字:“依赖注入 (Dependency Injection)”。 相对 IoC 而言,“依赖注入”的确更加准确的描述了这种古老而又时兴的设计理念。从名字上理解, 所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关 系注入到组件之中。 为什么称之为“古老而又时兴”的设计理念?至于“时兴”自然不必多费唇舌,看看国内外大小论坛 上当红的讨论主题便知。至于“古老”……,相信大家对下面图片中的设备不会陌生: 这就是笔者的主要工作装备,IBM T40 笔记本电脑一台、USB 硬盘和 U 盘各一只。想必大家在日常 工作中也有类似的一套行头。 这与依赖注入有什么关系? 图中三个设备都有一个共同点,都支持 USB 接口。当我们需要将数据复制到外围存储设备时,可以 根据情况,选择是保存在 U 盘还是 USB 硬盘,下面的操作大家也都轻车熟路,无非接通 USB 接口,然后 在资源浏览器中将选定的文件拖放到指定的盘符。 这样的操作在过去几年中每天都在我们身边发生,而这也正是所谓依赖注入的一个典型案例,上面称 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 之为“古老”想必也不为过分。 再看上例中,笔记本电脑与外围存储设备通过预先指定的一个接口(USB)相连,对于笔记本而言, 只是将用户指定的数据发送到 USB 接口,而这些数据何去何从,则由当前接入的 USB 设备决定。在 USB 设备加载之前,笔记本不可能预料用户将在 USB 接口上接入何种设备,只有 USB 设备接入之后,这种设 备之间的依赖关系才开始形成。 对应上面关于依赖注入机制的描述,在运行时(系统开机,USB 设备加载)由容器(运行在笔记本 中的 Windows 操作系统)将依赖关系(笔记本依赖 USB 设备进行数据存取)注入到组件中(Windows 文件访问组件)。 这就是依赖注入模式在现实世界中的一个版本。 很多初学者常常陷入“依赖注入,何用之有?”的疑惑。想来这个例子可以帮助大家简单的理解其中 的含义。依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建 一个灵活、可扩展的平台。将 USB 接口和之前的串/并、PS2 接口对比,想必大家就能明白其中的意味。 回顾 Quick Start 中的示例,UpperAction/LowerAction 在运行前,其 Message 节点为空。运行 后由容器将字符串“HeLLo”注入。此时 UpperAction/LowerAction 即与内存中的“HeLLo”字符串对 象建立了依赖关系。也许区区一个字符串我们无法感受出依赖关系的存在。如果把这里的 Message 属性 换成一个数据源(DataSource),可能更有感觉: java:comp/env/jdbc/sample 其中SampleDAO中的dataSource将由容器在运行期动态注入,而DataSource的具体配置和初始化工作 也将由容器在运行期完成。 对比传统的实现方式(如通过编码初始化DataSource实例),我们可以看到,基于依赖注入的系统实现相 当灵活简洁。 通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定SampleDAO中所需的 DataSource实例。SampleDAO只需利用容器注入的DataSource实例,完成自身的业务逻辑,而不用 关心具体的资源来自何处、由谁实现。 上面的实例中,我们假设SampleDAO是一个运行在J2EE容器中的组件(如 Weblogic)。在运行期,通 过JNDI从容器中获取DataSource实例。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 现在假设我们的部署环境发生了变化,系统需要脱离应用服务器独立运行,这样,由于失去了容器的支持, 原本通过JNDI获取DataSource的方式不再有效。我们需要如何修改以适应新的系统环境?很简单,我们 只需要修改dataSource的配置: org.gjt.mm.mysql.Driver jdbc:mysql://localhost/sample user mypass 这里我们的DataSource改为由Apache DBCP组件提供。没有编写任何代码我们即实现了DataSource的 切换。回想传统编码模式中,如果要进行同样的修改,我们需要付出多大的努力。 依赖注入机制减轻了组件之间的依赖关系,同时也大大提高了组件的可移植性,这意味着,组件得到重用 的机会将会更多。 依赖注入的几种实现类型 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Type1 接口注入 我们常常借助接口来将调用者与实现者分离。如: public class ClassA { private InterfaceB clzB; public init() { Ojbect obj = Class.forName(Config.BImplementation).newInstance(); clzB = (InterfaceB)obj; } …… } 上面的代码中,ClassA依赖于InterfaceB的实现,如何获得InterfaceB实现类的实例?传统的方法是在 代码中创建InterfaceB实现类的实例,并将起赋予clzB。 而这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有 了上面的代码,我们根据预先在配置文件中设定的实现类的类名,动态加载实现类,并通过InterfaceB强 制转型后为ClassA所用。 这就是接口注入的一个最原始的雏形。 而对于一个Type1型IOC容器而言,加载接口实现并创建其实例的工作由容器完成,如J2EE开发中常用的 Context.lookup(ServletContext.getXXX),都是Type1型IOC的表现形式。 Apache Avalon是一个典型的Type1型IOC容器。 Type2 构造子注入 构造子注入,即通过构造函数完成依赖关系的设定,如: public class DIByConstructor { private final DataSource dataSource; private final String message; public DIByConstructor(DataSource ds, String msg) { this.dataSource = ds; this.message = msg; } …… } 可以看到,在Type2类型的依赖注入机制中,依赖关系是通过类构造函数建立,容器通过调用类的构 造方法,将其所需的依赖关系注入其中。 PicoContainer(另一种实现了依赖注入模式的轻量级容器)首先实现了Type2类型的依赖注入模式。 Type3 设值注入 在各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得 力于Spring框架的影响)。 在笔者看来,基于设置模式的依赖注入机制更加直观、也更加自然。Quick Start中的示例,就是典 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 型的设置注入,即通过类的setter方法完成依赖关系的设置。 几种依赖注入模式的对比总结 接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有 限。 Type2和Type3的依赖注入实现模式均具备无侵入性的特点。在笔者看来,这两种实现方式各有特点, 也各具优势(一句经典废话)。 Type2 构造子注入的优势: 1. “在构造期即创建一个完整、合法的对象”,对于这条Java设计原则,Type2无疑是最好的 响应者。 2. 避免了繁琐的setter方法的编写,所有依赖关系均在构造函数中设定,依赖关系集中呈现, 更加易读。 3. 由于没有setter方法,依赖关系在构造时由容器一次性设定,因此组件在被创建之后即处于 相对“不变”的稳定状态,无需担心上层代码在调用过程中执行setter方法对组件依赖关系 产生破坏,特别是对于Singleton模式的组件而言,这可能对整个系统产生重大的影响。 4. 同样,由于关联关系仅在构造函数中表达,只有组件创建者需要关心组件内部的依赖关系。 对调用者而言,组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息,也为系统的 层次清晰性提供了保证。 5. 通过构造子注入,意味着我们可以在构造函数中决定依赖关系的注入顺序,对于一个大量 依赖外部服务的组件而言,依赖关系的获得顺序可能非常重要,比如某个依赖关系注入的 先决条件是组件的DataSource及相关资源已经被设定。 Type3 设值注入的优势 1. 对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系显得更加直 观,更加自然。 2. 如果依赖关系(或继承关系)较为复杂,那么Type2模式的构造函数也会相当庞大(我们需 要在构造函数中设定所有依赖关系),此时Type3模式往往更为简洁。 3. 对于某些第三方类库而言,可能要求我们的组件必须提供一个默认的构造函数(如Struts 中的Action),此时Type2类型的依赖注入机制就体现出其局限性,难以完成我们期望的功 能。 可见,Type2和Type3模式各有千秋,而Spring、PicoContainer都对Type2和Type3类型的依赖注 入机制提供了良好支持。这也就为我们提供了更多的选择余地。理论上,以Type2类型为主,辅之以Type3 类型机制作为补充,可以达到最好的依赖注入效果,不过对于基于Spring Framework开发的应用而言, Type3使用更加广泛。 September 2, 2004 So many open source projects. W hy not Open your Documents? SpringFrameW ork Developer’s Guide Version 0.6 Spring Bean 封装机制 Spring 从核心而言,是一个 DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代 码中涉及 Spring 专有类,即可将其纳入 Spring 容器进行管理。 作为对比,EJB 则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须 遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付 出极大的代价。 为了避免这种情况,实现无侵入性的目标。Spring 大量引入了 Java 的 Reflection 机制,通过动态 调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件 BeanFactory,以此作为其依赖注入 机制的实现基础。 org.springframework.beans 包中包括了这些核心组件的实现类,核心中的核心为 BeanWrapper 和 BeanFactory 类。这两个类从技术角度而言并不复杂,但对于 Spring 框架而言,却是关键所在,如果 有时间,建议对其源码进行研读,必有所获。 Bean Wrapper 从Quick Start的例子中可以看到,所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。 讲的通俗点,就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进 行设定。 我们知道,如果动态设置一个对象属性,可以借助Java的Reflection机制完成: Class cls = Class.forName("net.xiaxin.beans.User"); Method mtd = cls.getMethod("setName",new Class[]{String.class}); Object obj = (Object)cls.newInstance(); mtd.invoke(obj,new Object[]{"Erica"}); return obj; 上面我们通过动态加载了User类,并通过Reflection调用了User.setName方法设置其name属性。 对于这里的例子而言,出于简洁,我们将类名和方法名都以常量的方式硬编码。假设这些常量都是通过配 置文件读入,那我们就实现了一个最简单的BeanWrapper。这个BeanWrapper的功能很简单,提供一个 设置JavaBean属性的通用方法(Apache BeanUtils 类库中提供了大量针对Bean的辅助工具,如果有兴 趣可以下载一份源码加以研读)。 Spring BeanWrapper基于同样的原理,提供了一个更加完善的实现。 看看如何通过Spring BeanWrapper操作一个JavaBean: Object obj = Class.forName("net.xiaxin.beans.User").newInstance(); BeanWrapper bw = new BeanWrapperImpl(obj); bw.setPropertyValue("name", "Erica"); System.out.println("User name=>"+bw.getPropertyValue("name")); 对比之前的代码,相信大家已经知
本文档为【spring中文教程(spring开发指南)_Final】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_427986
暂无简介~
格式:doc
大小:2MB
软件:Word
页数:88
分类:互联网
上传时间:2011-08-31
浏览量:26