Spring ApplicationContext.xml配置的12个技巧_第1页
Spring ApplicationContext.xml配置的12个技巧_第2页
Spring ApplicationContext.xml配置的12个技巧_第3页
Spring ApplicationContext.xml配置的12个技巧_第4页
Spring ApplicationContext.xml配置的12个技巧_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

SpringSpring ApplicationContext xmlApplicationContext xml 配置的配置的 1212 个技巧个技巧 Spring 是一个强有力的 java 程序框架 其被广泛应用于 java 的程序中 它用 POJO 提供了企业级服务 Spring 利用依赖注入可以获得简单而有效的测试能 力 Spring beans 依赖关系 以及服务所需要的 bean 都将在配置文件中予以 描述 配置文件一般采用 XML 格式 然而 XML 配置文件冗长而不易使用 在你 进行一 个使用了大量 bean 的大项目中它将变得难以阅读和控制 在这篇文章中我将给你展示 12 种的有关 Spring XML 配置文件的最佳技巧 它 们中的一些具有更多的实际意义 而不仅是最好的技巧 请注意另外一些因素 例如域模型的设计 会影响到 XML 配置 但是这篇文章更关注于 XML 配置的可 读性和可操控性 1 1 避免使用自动装配 避免使用自动装配 Spring 可以通过 bean 类的自省来实现自动装配依赖 这样的话你就不必明确 地描述 bean 的属性或者构造函数的参数 根据属性名称活匹配类型 bean 属 性可以 自动进行装配 而构造函数可以根据匹配类型自动装配 你甚至可以设 置自动装配进行自动侦测 这样 Spring 替你就会选择一个合适的机制 请看下 面的例 子 Spring 可以通过 bean 类的自省来实现自动装配依赖 这样的话你就不必明确 地描述 bean 的属性或者构造函数的参数 根据属性名称活匹配类型 bean 属 性可以 自动进行装配 而构造函数可以根据匹配类型自动装配 你甚至可以设 置自动装配进行自动侦测 这样 Spring 替你就会选择一个合适的机制 请看下 面的例 子 OrderService 类的属性名被用来和容器中的一个 bean 实例进行匹配 自动装 配会默默的保存一些类型信息并降低混乱 然而 由于它会牺牲掉这种配置的 直观性和可维护性 你在实际的项目中将不会用到它 许多指南和陈述材料都 把它吹捧为 Spring 的一个非常 cool 的特性 而没有提到它的这个缺点 依我 之见 就像 Spring 的对象池一样 它更多了一些商业味道 它看起来好像可 以使 XML 配置文件更精简一些 但实际上却增加其复杂性 尤其是在你的较大 规模的工程中 已经定义了很多 bean 的时候更是如此 Spring 允许你混合使用 自动和手动装配 但是这种矛盾会使 XML 配置更加的令人费解 2 2 使用命名规范 使用命名规范 和 Java 编码的理念一样 在项目中始终用清晰的 描述性的 一致的命名规 范对开发人员理解 XML 配置非常有用 拿 bean ID 举例来说 你可以遵循 Java 类中属性的命名规范 比如说 OrderServiceDAO 的 bean ID 应该是 orderServiceDAO 对于大项目来说 在 bean ID 前加包名来作为前缀 3 3 使用简化格式 使用简化格式 简化格式有利于减少冗余 因为它把属性值和引用作为属性 而不是子元素 看下面的例子 lizjason 以上程序可以重新以简化格式书写为 简化格式在 1 2 版本时已经可用了 但请注意不存在这种简 化格式不仅可以较少你的代码输入量 而且可以使 XML 配置更加的清晰 当你 的配置文件中存在大量的 bean 定义时 它可以显著地提高可读性 4 4 尽量使用 尽量使用 typetype 而不是而不是 indexindex 去解决构造函数参数的匹配问题去解决构造函数参数的匹配问题 当构造函数中有多个同类型的参数时 Spring 只允许你使用从 0 开始的 index 或者 value 标签来解决这个问题 请看下面的例子 最好用 type 属性取代上面的做法 用 index 可以稍微减少冗余 但是它更容易出错且不如 type 属性可读性高 你 应该仅在构造函数中有参数冲突时使用 index 5 5 如可能 尽量复用 如可能 尽量复用 beanbean 定义定义 Spring 提供了一种类似于继承的机制来降低配置信息的重复并使 XML 配置更加 的简单 一个子 bean 可以从它的父 bean 继承配置信息 本质上这个父 bean 就 像 它的子 bean 的一个模板 这是一个在大型项目中必须使用的特性 所有你 要做的就是把父 bean 的 abstract 属性置为 true 并在子 bean 中加 以引用 例如 shippingService bean 继承了 abstractService bean 的属性 companyName 的 值 lizjason 注意 如果你为 bean 声名一个 class 或工厂方法 这个 bean 将 会默认为 abstract 6 6 尽量使用 尽量使用 ApplicationContextApplicationContext 装配装配 beanbean 而不是用 而不是用 importimport 像 Ant 脚本中 imports 一样 Spring 的 import 元素对于模块化 bean 的装配非 常有用 例如 然而 比起在 XML 中用 imports 预装配这些 bean 利用 ApplicationContext 来配置它们将更加灵活 也可以使 XML 配置更加的易于管理 你可以像下面这 样传递一个 bean 定义数组到 ApplicationContext 的构造函数中 String serviceResources orderServices xml billingServices xml shippingServices xml ApplicationContext orderServiceContext new ClassPathXmlApplicationContext serviceResources 7 7 用 用 idid 来标识来标识 beanbean 你可以用 id 或名字作为 bean 的标识 用 id 可读性较差 但是它可以影响 XML 分析器使 bean 的 reference 有效 如果 id 由于 XML IDREF 约束而无法使用 你可以用 name 作为 bean 的标识 XML IDREF 约束是指 id 必须以字母开始 或 者是在 XML 声名了的一个标点符号 后面可以是字母 数字 连字符 下划线 冒号或 full stops 不知道怎么翻译好 在实际应用中很少会遇到 XML IDREF 约束问题 8 8 在开发阶段使用依赖检查 在开发阶段使用依赖检查 你可以为 bean 的 dependency check 属性设置一个值来取代默认的 none 比如 说 simple objects 或者 all 这样的话容器将替你做依赖有效性的检查 当 一个 bean 的所有属性 或者某些属性目录 都被明确设置 或利用自动装配时将 会非常有用 在这个例子中 容器将确保这些属性不是 privitives 或者保证 collections 是 为 orderService bean 设置的 为所有的 bean 设置默认的依赖检查是可能的 但这个特性由于有些 bean 的属性不需要设置而很少使用 9 9 为每个配置文件加一个描述注释 为每个配置文件加一个描述注释 在 XML 配置文件中最好使用有描述性的 id 和 name 而不是成堆的注释 另外 加一个文件描述头将会非常有用 这个描述可以概括文件中定义的 bean 另一 个选择 你可以在 description 元素中加入描述信息 例如 This file defines billing service related beans and it depends on baseServices xml which provides service bean templates 用 description 元素的一个好处就是工具可以很容易的把描述信息从这个元素 中提取出来 1010 和和 teamteam membersmembers 沟通变更沟通变更 当你修改 java 源码后 要确保更改了配置文件中的相应部分并把这个情况告知 你的 team members XML 配置文件也是代码 它们是程序的重要组成部分 但 它们很难阅读和维护 大多数时间里 你需要同时看 XML 配置文件和 java 代码 才能知道是怎么回事 1111 settersetter 注入和构造函数注入 优先使用前者注入和构造函数注入 优先使用前者 Spring 提供了三种注入方式 构造函数注入 setter 注入和方法注入 一般我 们使用前两种 在这个例子中 orderService bean 用了构造函数注入 而 BillingService bean 用了 setter 注入 构造函数注入可以确保 bean 正确地构建 但是 setter 注入更加的灵活和易于控制 特别是当 class 有多个属性并且它们中的一些是 可选的情况是更是如此 1212 不要滥用注入不要滥用注入 就像前面提到的 Spring 的 ApplicationContextEclipse and IntelliJ java 代码更加的易于阅读 维护和管理比使 XML 文件可以替你创建 java 对象 但不 是所有的 java 对象都应该通过注入创建 例如 域对象就不应该通过 ApplicationContext 创建 Spring 是一个优秀的框架 但是考虑到可读性和可 操控性 基于 XML 配置的配置会在定义很多 bean 的时候出现麻烦 过渡使用依 赖注入将会使 XML 配置更加的复杂和冗长 切记 当使用高效的 IDE 时 例如 结论结论 XML 是 Spring 流行的配置格式 存在大量 bean 定义时 基于 XML 的配置会变 得冗长而不易使用 Spring 提供了丰富的配置选项 适当地使用这些选项可以 使 XML 配 置更加的清晰 但其它的一些选项 例如自动装配 可能会降低可读 性和可维护性 参考本文中提到的这些技巧可能会帮助你创建干净而易读的 XML 配置文件 14 1 id Bean 的唯一标识名 它必须是合法的 XML ID 在整个 XML 文档中 唯一 2 name 用来为 id 创建一个或多个别名 它可以是任意的字母符合 多 个别名之间用逗号或空格分开 3 class 用来定义类的全限定名 包名 类名 只有子类 Bean 不用定 义该属性 4 parent 子类 Bean 定义它所引用它的父类 Bean 这时前面的 class 属 性失效 子类 Bean 会继承父类 Bean 的所有属性 子类 Bean 也可以覆盖父类 Bean 的属性 注意 子类 Bean 和父类 Bean 是同一个 Java 类 5 abstract 默认为 false 用来定义 Bean 是否为抽象 Bean 它 表示这个 Bean 将不会被实例化 一般用于父类 Bean 因为父类 Bean 主要是供 子类 Bean 继承使用 6 singleton 默认为 true 定义 Bean 是否是 Singleton 单例 如果设为 true 则在 BeanFactory 作用范围内 只维护此 Bean 的一个实例 如果设为 flase Bean 将是 Prototype 原型 状态 BeanFactory 将为每 次 Bean 请求创建一个新的 Bean 实例 7 lazy init 默认为 default 用来定义这个 Bean 是否实现懒初 始化 如果为 true 它将在 BeanFactory 启动时初始化所有的 Singleton Bean 反之 如果为 false 它只在 Bean 请求时才开始创建 Singleton Bean 8 autowire 自动装配 默认为 default 它定义了 Bean 的自动装 载方式 1 no 不使用自动装配功能 2 byName 通过 Bean 的属性名实现自动装配 3 byType 通过 Bean 的类型实现自动装配 4 constructor 类似于 byType 但它是用于构造函数的参数的自动组装 5 autodetect 通过 Bean 类的反省机制 introspection 决定是使用 constructor 还是使用 byType 9 dependency check 依赖检查 默认为 default 它用来确保 Bean 组件通过 JavaBean 描述的所以依赖关系都得到满足 在与自动装配功能 一起使用时 它特别有用 1 none 不进行依赖检查 2 objects 只做对象间依赖的检查 3 simple 只做原始类型和 String 类型依赖的检查 4 all 对所有类型的依赖进行检查 它包括了前面的 objects 和 simple 10 depends on 依赖对象 这个 Bean 在初始化时依赖的对象 这个对 象会在这个 Bean 初始化之前创建 11 init method 用来定义 Bean 的初始化方法 它会在 Bean 组装之后调 用 它必须是一个无参数的方法 12 destroy method 用来定义 Bean 的销毁方法 它在 BeanFactory 关闭 时调用 同样 它也必须是一个无参数的方法 它只能应用于 singleton Bean 13 factory method 定义创建该 Bean 对象的工厂方法 它用于下面的 factory bean 表示这个 Bean 是通过工厂方法创建 此时 class 属 性失效 14 factory bean 定义创建该 Bean 对象的工厂类 如果使用了 factory bean 则 class 属性失效 下面列出元素的所有可用的指定方式 bean 可以在当前文件中查找依赖对象 也可以在应用上下文 ApplicationContext 中查找其它配置文件的对象 local 只在当前文件中查找依赖对象 这个属性是一个 XML IDREF 所以它指 定的对象必须存在 否则它的验证检查会报错 external 在其它文件中查找依赖对象 而不在当前文件中查找 总的来说 和大部分的时候可以通用 bean 是最灵活的方式 它允许你在多个文件之间共享 Bean 而 local 则提供了便利的 XML 验证 如何使用 spring 的作用域 这里的 scope 就是用来配置 spring bean 的作用域 它标识 bean 的作用域 在 spring2 0 之前 bean 只有 2 种作用域即 singleton 单例 non singleton 也称 prototype Spring2 0 以后 增加了 session request global session 三种专用于 Web 应用程序上下文的 Bean 因此 默认情况下 Spring2 0 现在有五种类型的 Bean 当然 Spring2 0 对 Bean 的类型的设计进行了重构 并设计出灵活的 Bean 类型支持 理论上可以 有无数多种类型的 Bean 用户可以根据自己的需要 增加新的 Bean 类 型 满 足实际应用需求 1 singleton 作用域 当一个 bean 的作用域设置为 singleton 那么 Spring IOC 容器中只会存在 一个共享的 bean 实例 并且所有对 bean 的请求 只要 id 与该 bean 定义相匹 配 则只会返回 bean 的同一实例 换言之 当把 一个 bean 定义设置为 singleton 作用域时 Spring IOC 容器只会创建该 bean 定义的唯一实例 这个 单一实例会被存储到单例缓存 singleton cache 中 并且所有针对该 bean 的后续请求和引用都 将返回被缓存的对象实例 这里要注意的是 singleton 作 用域和 GOF 设计模式中的单例是完全不同的 单例设计模式表示一个 ClassLoader 中 只有一个 class 存在 而这里的 singleton 则表示一个容器对 应一个 bean 也就是说当一个 bean 被标识为 singleton 时 候 spring 的 IOC 容器中只会存在一个该 bean 配置实例 或者 2 prototype prototype 作用域部署的 bean 每一次请求 将其注入到另一个 bean 中 或者 以程序的方式调用容器的 getBean 方法 都会产生一个新的 bean 实例 相当 与一个 new 的操作 对于 prototype 作用域的 bean 有一点非常重要 那就是 Spring 不能对一个 prototype bean 的整个生命周期负责 容器在初始化 配 置 装饰或者是装配完一个 prototype 实例后 将它交给客户端 随后就对该 prototype 实例不闻不问了 不管何种作用域 容器都会调用所有对象的初始 化生命周期回调方法 而对 prototype 而言 任何配置好的析构生命周期回调 方法都将不会被调用 清除 prototype 作用域的对象并释放任何 prototype bean 所持有的昂贵资源 都是客户端代码的职责 让 Spring 容器释放被 singleton 作用域 bean 占用资源的一种可行方式是 通过使用 bean 的后置处 理器 该处理器持有要被清除的 bean 的引用 配置实例 或者 3 request request 表示该针对每一次 HTTP 请求都会产生一个新的 bean 同时该 bean 仅 在当前 HTTP request 内有效 配置实例 request session global session 使用的时候首先要在初始化 web 的 web xml 中做如下配置 如果你使用的是 Servlet 2 4 及以上的 web 容器 那么你仅需要在 web 应用的 XML 声明文件 web xml 中增加下述 ContextListener 即可 org springframework web context request RequestContextListener 如果是 Servlet2 4 以前的 web 容器 那么你要使用一个 javax servlet Filter 的实现 requestContextFilter org springframework web filter RequestContextFilter requestContextFilter 接着既可以配置 bean 的作用域了 4 session session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean 同时该 bean 仅在当前 HTTP session 内有效 配置实例 配置实例 和 request 配置实例的前提一样 配置好 web 启动文件就可以如下配置 5 global session global session 作用域类似于标准的 HTTP Session 作用域 不过它仅仅在基 于 portlet 的 web 应用中才有意义 Portlet 规范定义了全局 Session 的概念 它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享 在 global session 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围 内 如果你在 web 中使

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论