MyEclipse Logo

MyEclipse Spring 入门教程
翻译: 刘长炯 BeanSoft@126.com
Blog: http://www.blogjava.net/beansoft/
日期: 2007-11-26
声明: 中文文字版权归 刘长炯 所有, 原文及相关的图片等资源的版权归原作者 Genuitec L.L.C 公司所有.

目录

  1. 简介
  2. 建议的听众
  3. 系统需求
  4. Spring 介绍
  5. 开始工作
  6. 可视化项目
  7. 理解和运行代码
  8. 修改项目
  9. 小结
  10. FAQ
  11. 资源
  12. 反馈

1. 简介

欢迎来到 MyEclipse 的 Spring 入门教程. 在这个教程中我没将会覆盖 Spring 框架的一些基础功能, 例如依赖注入, 并展示了如何使用 MyEclipse 来帮助你开发Spring 应用程序.

因为 Spring 是一个包含了大量功能的框架, 这个教程将会集中精力在依赖注入上, 它是 Spring 的核心功能之一并渗透到了 Spring 的方方面面. 简单的来说, 依赖注入是用来管理框架的一种思路, 在需要引用的时候才给对象赋一个引用值. 这使开发人员不再需要获得对象引用的时候调用属性设置器(setter)或者通过 JNDI 来查找. 如果系统定义的很清楚, 例如使用 XML 或者注释来定义, 然后 Spring 运行时将会知道合适需要注入依赖并确保正确的注入内容. 通过删除 "对象记事薄", 开发人员可以更容易的关注应用程序的逻辑层.

这个对 Spring 内核的简化视图是我们将会在这个教程里面了解的内容. 另外, 这个教程也使用了 Spring 1.x 的惯例, 没有包含一些 Spring 2.0 中所支持的注释支持. 我们将会发布一个新版的教程, 将会包含一些 Spring 2.0 版本的扩展的内容.

教程中所用的 Knight(骑士) 例子代码来自于书籍 Spring in Action. 项目的内容稍作修改, 去掉了任何编译警告 并能用更少的代码来清楚的显示例子.

2. 建议的听众

这个教程的目标受众是那些好歹对 MyEclipse 或者 Eclipse 有所了解的开发人员, 应该掌握使用 IDE 进行浏览以及理解一些常见的概念例如 "View 视图" . 尽管这个教程介绍了一些 Spring 的基础知识, 但是这并不能代替 Spring 官方网站的详细文档, 这些信息位于文末的 资源 部分.

如果您对 MyEclipse 和 Spring 都感到不熟悉, 这个教程可以帮你熟悉两个部分的基础知识.  要学习更多的 MyEclipse 或者 Spring 文档, 请阅读我们的产品 文档 或者文末的 资源 部分.

3. 系统需求

这个教程基于 MyEclipse 5.1 制作, 捆绑的是 Spring 1.3 类库. 如果你在使用其它版本的 MyEclipse, Hibernate, 绝大部分的屏幕操作和说明都将是十分相似的. 如果你使用的是 Spring 2.x, 它将会向后兼容教程里面使用的所有概念.

如果你使用的是最新版本的 MyEclipse, 并且发现本教程的一些部分和你使用 MyEclpse 时所看到的屏幕不一样, 请 告诉我们 , 我们(注: MyEclipse 文档团队, 不是我, 翻译这份文档的人) 将会确保解决任何不一致的地方.

4. Spring 介绍

要介绍 Spring 比起介绍其它框架来说相对比较困难, 这是因为它不是个单一目标的技术. 可以认为 Spring 是一个巨大的框架, 几乎包含了 Java 软件开发中的各个方面的最佳实践(译者注: Spring 神话刚出现时候的典型技术推广辞, 这句话总是被用到新出现的框架/技术上). 从 Plain-Old-Java-Object (POJO) 开发, 到 网络应用程序开发, 到企业应用程序开发, 到持久层管理以及面向切面编程(AOP). 在 Java 工业界, Spring 支持所有的这些并在大部分方面实现了设计良好和易于测试的代码.

因为个头太大, 我们的教程将会集中精力到最简单的 Spring 应用程序, 使用依赖注入来开发 POJO 应用. 澄清一下, 依赖注入是 Spring 中所使用的一种机制, 用来处理在父对象需要子对象的引用的时候正确的创建并初始化子对象. 一个典型的实用例子是企业的 Java 应用中的网站开发来直接访问数据访问层来从数据库中读取或者写入对象(注: 不通过显式的赋值来使用数据层). 这是一个经典的例子, 当网站应用需要读取或者保存对象时, 允许 Spring 向 web 层中的 POJO 注入数据访问层.

为了从你的脑子里消除对这个过程的神秘感, 我们可以告诉大家, Spring 1.2 是通过 XML 配置文件来完成对象引用关系映射配置, Spring 2.0 则是通过 Java 5 注释来完成.

使用声明的方式, Spring 开发人员可以真正的将程序的各个部分软连接起来, 通过使用注释或者 XML 配置文件的方式, 程序运行的时候 Spring 能够 "按需" 创建或者初始化所有的对象关系. 软连接一切的好处就是程序的各个部分可以很容易的切换到另一个实现(例如:测试实现), 只需要修改注释或者 XML 配置文件, 然后再次运行程序即可. 在一些情况下甚至不需要重新编译程序. 这对开发人员来说是个很大的方便之处, 例如需要持续测试或者发布大型应用的各个部分. Spring 对这些问题的思考提供了很自然的方式, 鼓励你用模块化的架构来维护应用, 支持插拔能力(注: 不是热插拔).

要了解更多 Spring 的内容, 建议您首先阅读 资源 部分的 Spring 介绍教程.

5. 开始工作

在这个教程中我们将会使用稍作修改(而且简化过的) Knight(骑士) Spring 程序, 来自书籍 Spring in Action , 因为这个例子简单而且著名. 

你可以在 这里 下载这个 MyEclipse Spring 项目的 ZIP 版本, 或者从我们的 资源 部分的链接来下载. 你可以将这个教程导入到你的 MyEclipse 工作区, 通过菜单 File > Import > Existing Project 功能, 如下所示:

图 1. 使用导入功能来加载示例项

当项目导入后, 我们可以使用一些 MyEclipse 的高级软件开发功能来更好的理解 Spring 应用程序是如何组织的.

6. 可视化项目

首先我们来从所有的源代码来创建个新的 UML 类图来看看这些类是如何互相关联的. 刚才导入的项目已经包含了这个 UMR (UML Model Repository, UML 模型仓库) 文件, 位于 src/java 目录的根路径下, 文件名是 Knight.umr. 双击可以打开这个图, 如下所示:

UML class diagram of Knight application
图 2. Knight 应用的 UML 类图

这幅图向我们展示了这个程序所包含的 knights, quests, exceptions 以及其它类之间的关系. 这个程序非常小, 不过你也可以很容易的反向工程一个大应用来看看其组织思路. 在这个特殊情况下, 我简单的在 Package Explorer 视图中选中类, 然后把它们拖放到新建的类图上就得到了这个结果.

能看看 UML 类图固然很好, 不过它并不能告诉我们完整的故事, 尤其对于 Spring 应用程序来说. 为此, 如果我们能够看到程序里面不同的 bean 之间的可视化关系该多好啊... 不过你真是走大运了, MyEclipse 能做到!

首先, 你得打开 Spring Beans 视图. 这个视图显示了 Spring 程序中通过或者一个或者多个 Spring bean 配置文件所配置的所有 bean. 这些配置文件不必有明确的命名约定 (例如 struts-config.xml, faces-config.xml, 等等.), 而且一个程序可以包含任意个数的 bean 配置文件. 因此, MyEclipse 允许你来配置 XML 文件列表来展示你的 bean 配置信息. 这个信息可以在项目属性里找到, 在 MyEclipse > Spring 下, 如下图所示:

图 3. Spring 项目的 bean 配置文件列表

现在我们来真正打开 Spring Bean 视图, 你可以通过选择菜单来打开: Window > Show View > Other... > MyEclipse Enterprise Workbench > Spring Beans. 当 Spring Beans 视图打开后, 甚至可以可视化的显示 Spring bean 间的关系图, 如下所示:

图 4. 打开 Spring Beans 视图以及可视化显示 Bean

从我们的 Spring bean 图中我们可以看到 Knight 已经引用了一个 minstrel(歌手), 而 knightTarget 则引用了一个需要 Knight 完成的 quest(任务). 在这个程序里面我们将会真正的使用 Aspect Oriented Programming (AOP) , 通过一个拦截器来实现 minstrel.

7. 理解和运行代码

我们的 minstrel 会 "歌颂" (实际上是打印日志) 所有 Knight 即将要做的任务, 通过 "before" 方法拦截器来实现. 简而言之, "before" 拦截器就是个简单的方法来执行一项动作 (例如向控制台打印一些信息来显示我们的 Knight 即将要做的事情), 在真正的操作发生 "之前" 执行. 为了实现这个目标, 可以指示 Spring 来将这个拦截器加到 bean 定义的其它类上. web 开发人员读到这里的时候, 你可以立即看到一个这样的应用: (译注:自动)处理事务.

MyEclipse 将会帮助你快速的浏览 Spring 应用程序. 在这种情况下, 让我们来看看到底 minstrel 是如何实现的. 在图上双击 minstrel bean, 跳转到 Spring bean 配置文件中的这个 bean 的定义处, 然后使用 CTRL 键+鼠标左键点击 , 这样我们就可以直接跳转到 minstrel 类的实现代码了, 如下所示:

图 5. 定位到 minstrel 的实现代码

可以看到 minstrel 实现的非常简单, 它所做的就是打印一下 Knight 所进行的操作的日志. 要运行这个 Spring 程序, 你可以运行类 com.springinaction.chapter01.knight.KnightApp , 然后你会在控制台上得到下面的输出:

[DEBUG] 10:51:03 KnightApp - Running KnightApp
[DEBUG] 10:51:04 KnightOfTheRoundTable - Brave Bedivere did embarkOnQuest
[DEBUG] 10:51:04 KnightApp - KnightApp Finished
图 6. 控制台上默认 minstrel 的输出

你可以看到默认的 minstrel 实现输出了信息 "Brave Bedivere did embarkOnQuest". 如果我们想换一个完全不同的 minstrel 实现, 但是却不想修改 MinstrelAdvice 类的任何代码, 当然没有任何问题. 我们只需要写一个新的 minstrel 实现, 然后使用 Spring 把它插入进去.

8. 修改项目

要创建一个新的 minstrel , 我们将会复制一份 MinstrelAdvice 类, 名字改成 BetterMinstrelAdvice. 这个类的代码清单如下所示 ( 下载):

package com.springinaction.chapter01.knight;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;

public class BetterMinstrelAdvice implements MethodBeforeAdvice
{
    public void before(Method method, Object[] args, Object target)
            throws Throwable
    {

        Knight knight = (Knight) target;

        Logger song = Logger.getLogger(target.getClass());

        song.debug("La la lee la, our fair knight " + knight.getName() + " has performed " + method.getName() + " with such grace!");
    }
}
图 7. BetterMinstrelAdvice 类的实现代码

可以注意到这个实现依然很简单, 但是这个歌手将会唱一首更动听的歌并更热情的表扬骑士所做的一切. 要将这个新的实现插入到 Spring 程序中, 有两步可以做:

  1. 在 bean 配置文件中创建一个新的 bean 定义
  2. 替换 Knight 的 minstrel 拦截器 为新的 betterMinstrel interceptor

详细步骤如下所示:

图 8. 创建一个新 minstrel 并插入进去

当新的 betterMinstrel bean 插入到 knight bean 后, 然后不做其它任何改动重新运行一下示例程序, 你可以注意到控制台的输出已经变成了这样:

[DEBUG] 11:38:57 KnightApp - Running KnightApp
[DEBUG] 11:38:57 KnightOfTheRoundTable - La la lee la, our fair knight Bedivere has performed embarkOnQuest with such grace!
[DEBUG] 11:38:57 KnightApp - KnightApp Finished 
图 9. 新 betterMinstrel 实现类 的控制台输出

你可以看到 Spring 的可插入性给你的项目所带来的价值. 一种最常用的程序不同部分的可插拔性的应用场景就是测试. 考虑一下 web 应用程序; 你可以写一些模拟的 DAO 实现类, 然后把他们插入进去, 这样在测试之前就不需要做其它的任何改动(译者注: 代码上的). 你可以通过 Spring 将测试类连接到测试的 DAO 实现, 而不用真正实现类外加一个数据库连接来进行测试.

其它例子可以将整个应用的实现进行切换(例如缓存, 数据库访问, 等等), 而不会影响程序的执行, 或者花费时间手工重构类或者修改源码来修改类中的引用.

9. 小结

尽管这个教程里面的程序非常简单, 提供的技术和信息对理解 Spring 和 MyEclipse 都是非常关键的. 我们看到了一些写的很不错的代码已经 Spring 可视化技术, 这样你可以更好的理解正在开发的应用, 并可以为其它人提供更容易理解的文档(译注: 反过来说如果没有文档和注释, 只有不含注释 XML 配置文件, Spring 应用程序的维护和修改是相当困难的).

另外, 我们展示了 Spring 特定的工具, 向导和界面, 可以使你不用手工修改 XML 文件就可以改动应用程序, 并展示了如何无缝替换运行的程序的一部分为新的实现.

希望本教程对你有所帮助. 如果你对本教程有任何建议或者问题, 请 告诉我们. 用户的反馈对我们编写这些教材是非常用价值的.

10. FAQ

现在暂时没有任何问题...

11. 资源

下面是一些资源的链接, 我们希望能帮助解答您在阅读本教程中遇到的大部分关于 Spring 的问题. Spring 是一个集中了开发场景中的各个方面最佳实践的框架. 因此, 要获取 Spring 某些部分的问题的答案将会十分费劲. 下面我们给大家提供了一些 Spring 主要用途的参考资料(译注: 英文的, 有一些是有中文版的, 建议 Google 搜索一下):

参考

基础

网站开发

企业应用

12.反馈

我们非常希望听到您的声音! 如果你喜欢本教程, 有建议甚至错误修正建议, 请告诉我们. 我们通过 文档论坛 来跟踪所有用户对学习资料的建议.  请告诉我们您正在评论的是哪份 MyEclipse 资料这样我们可以更快的查明出现问题的章节.