理解企业平台

Microsoft Corporation

摘要:包括两部分。第一部分是介绍在有经验的 J2EE 开发人员看来 .NET 是什么样子的。它把 .NET 概念与您已经理解的原理结合起来,说明了两个平台的不同与相似之处。本章的第二部分是镜像,提供的信息是相同的,但只针对有经验的 .NET 开发人员。为您介绍了 J2EE 的企业特性,并解释了 Java 应用程序是如何在分布式环境中工作的。

简介

本章为有某种平台开发经验但没有接触过这种替代技术的开发人员简要介绍了背景情况。这不是一本培训手册,但结合您已了解的其他环境,可以帮助您理解某种环境的基本概念。

Microsoft 平台和 Sun 平台之间的竞争就如 Apple 用户界面的拥护者和 Windows 的支持者之间的竞争一样根深蒂固。但是,公司业务不断增长的现实情况是:公司执行组件使用的是最能满足他们要求的平台,而不是固守这种或那种特殊的意识形态。

作为一个 J2EE 开发人员,在其职业生涯中根本不接触 Microsoft .NET 的机会越来越少了。实际上,对于雇主来说,同时精通 .NET 和 J2EE 是一件非常有吸引力的事情。同样,如果您是一位 .NET 开发人员,但没用过 Java,则本章的第二部分可以帮助您理解 J2EE 平台的功能。此外,这并不是一本参考书,而是试图把 J2EE 领域的概念与您已有所了解的 .NET 概念关联起来。

如果您是一位有经验的 Microsoft .NET 开发人员,请转到“J2EE 基本原理(针对 .NET 开发人员)”一节。

本章末的汇总表列出了 .NET 和 J2EE 的等效组件。

Microsoft .NET 基本原理(针对 J2EE 开发人员)

Microsoft .NET 的名称反映了 Microsoft 将重心重新调整为 Internet 上的操作和分布式应用。Microsoft .NET 由三个主要部分组成:

一种与语言无关的应用环境,可以优化分布式操作.NET Framework

一种可以使用几种 Microsoft 语言编程的开发环境Visual Studio .NET

支持分布式环境和 .NET Framework的操作系统Windows Server System

最初是想将 .NET 实现为有如下特点的一种统一体:

与语言无关的编程。

企业级可扩展性和可靠性。

集成安全性。

易于实现。

分布式操作。

支持开放标准。

可靠的操作和可管理性。

强大的调试工具。

.NET 与 J2EE 对比

在经验丰富的 Java 开发人员看来,.NET 可能与 Java 平台很相似,它们都提供了一种创建应用程序的结构化方法,都有编译为中间代码的语言,都为应用程序开发提供了一个大型 API 库。的确,许多 Java 领域评论员已经指出,从 J2EE 到 .NET 的概念跳跃似乎要比从 Windows DNA 到 .NET 的概念跳跃幅度小一些。但实际上,.NET 的核心有一套与 Java 平台不同的目标。

Java 包括 Java 平台(运行库与 API)和 Java 语言。Java 平台的用途是支持用 Java 语言编写并被编译为 Java 字节码的应用程序。尽管进行了许多试图将其他语言编译为 Java 字节码的工作,但是这些工作大部分都是学术活动。Java 的一贯思想就是在多种操作系统上使用一种语言

.NET 包括 .NET Framework(运行库间与 API)和支持的多种编程语言。.NET Framework 的目标就是支持用任何语言编写并且被编译成 Microsoft 中间语言 (MSIL) 的应用程序。.NET 的目标是“多种语言共享一种平台”。

研究 .NET Framework

了解 .NET Framework 以及它为基于 .NET 的应用程序提供的服务非常重要。

.NET 的应用或者基于 .NET Framework 的应用都指的是使用 .NET Framework 的应用。为简单起见,本书使用了一些基于 .NET 的应用。

.NET Framework 包括的类库为数据访问、安全性、文件 I/O、XML 操作、消息传递、类反射、XML Web 服务、ASP.NET 和 Microsoft Windows 服务在内的各种任务提供了支持。

有时会对比 .NET Framework 和 Java 2 SDK,但二者却不是完全对等的。

.NET Framework 的核心部分就是支持 XML 网络服务。这项技术既是一种方法,也是在不同计算机、不同网络及不同操作系统的组件之间传递信息的传输层。

图 2.1 说明了 .NET Framework 的主要组成部分。


2.1依赖 CLR 的 .NET Framework 组件

.NET Framework 作为组件可以自由重新发布,它包括工具、类以及 API 支持以运行基于 .NET 的应用程序。希望运行基于 .NET 的应用程序的计算机上必须要安装有 .NET Framework。

Windows XP Service Pack 1 包含有 .NET Framework 1.0 版,Windows?Server 2003 带有 .NET Framework 1.1,它们是操作系统的一部分。对于较早的 Windows 版本,您可以从 MSDN Web 站点下载 .NET Framework 您也可以从 Windows 更新服务安装 .NET Framework。

.NET Framework SDK 中包含有可重新发布的 .NET Framework 包。

有多种方法可以将 .NET Framework 安装到客户端计算机上。可以把可重新发布的 .NET Framework 包解压为 .msi 文件,这样您(或者您的网络管理员)随之就可以利用 Active Directory 组策略将其分发。较大的企业也可以利用系统管理服务器来分发此包。较小的公司可以选择软件更新服务 (SUS) 来将 .NET Framework部署到 Windows 2000 客户端上。开发人员可以将可重新发布的包包含到 Visual Studio .NET 的编译输出中,添加可以检测客户端上是否有 .NET Framework 的例程,如果需要还可以安装或更新 .NET Framework。

公共语言运行库

公共语言运行库 (CLR) 是 .NET Framework 的核心组件。CLR 为承载和运行基于 .NET 的应用程序提供核心功能。 CLR 的主要功能如下:

实时 (JIT) 编译成本机代码。

跨语言集成。

内存管理与垃圾回收。

托管代码操作。

实时调试。

异常处理。

安全性。

运行时类型安全检查。

线程管理。

尽管有一些不同之处,但仍可将 CLR 看作是实现 Java 虚拟机 (JVM) 的作用。

实时 (JIT) 编译成本机代码

当部署并运行应用程序时,JIT 编译器要快速检查平台的规格。例如,编译器将要检查的方面包括处理器的类型与数量、内存等。然后 JIT 编译器编译应用程序,生成 执行环境 下的机器代码。这就是 JIT 编译过程。

.NET Framework 中的 JIT 过程类似于 JVM 的运行时编译器。

Windows NT 4.0 之后的 Windows 版本仅支持 x86 环境,这经常会使人们感到困惑:他们为何要为在 x86 平台上直接编译 MSIL 的正确步骤而烦恼。但是,基于 x86 的计算机并不都一样,MSIL 的使用为将来的操作系统开发提供了最大限度的灵活性。

JIT 编译考虑了这样的事实:一个应用程序在执行期间可能不会调用所有的程序代码。执行期间,不是使用处理器时间和内存来将可移植可执行文件 (PE) 中所有的 MSIL 转换为本机代码,而是在需要时才转换 MSIL,并存储得到的本机代码以备随后的调用可以访问它。当加载某类型时,加载程序为该类型的每个方法创建与附加一个 stub。最初调用该方法时,stub 将控制权传递给 JIT 编译器,它将该方法的 MSIL 转换成本机代码,并将该 stub 更改为直接在本机代码的位置执行。随后调用 JIT 编译的方法时就直接调用先前生成的本机代码,减少了花在 JIT 编译和运行代码上的时间。

JIT 操作的效果就是,首次执行应用程序时启动应用程序花费的时间稍微长一点。但是,执行对该 JIT 方法的第二次和以后的调用时的速度就会比预编译的应用程序快,这是因为 JIT 组件返回了先前生成的本机代码,对该计算机进行了适当的优化。

运行库提供了另外一种编译模式,称为安装时代码生成。与常规的 JIT 编译器一样,安装时代码生成模式将 MSIL 转换成本机代码,但每次转换的代码单元较大,并存储得到的本机代码以备随后加载和运行程序集时使用。利用安装时代码生成模式,安装应用程序将完整的程序集转换成本机代码时,考虑了关于当前已安装的所有程序集已知的信息。得到的文件其加载与启动速度比用标准 JIT 选项转换得到的本机代码的速度要快。

跨语言集成

当得知 CLR 只支持一种类型的代码时,您也许会感到奇怪。您也许会说,上一页宣称的与语言无关是什么意思呢?答案是,CLR 只支持 MSIL。灵活之处在于任何支持 .NET 的编程语言都能够产生 MSIL 输出。这就是与语言无关的缘由。您可以用下面的一种或多种语言创建基于 .NET 的应用程序:

托管 C++(这里不足为奇)

C# (类似于 Java 和 C++ 的 C Sharp 鈥_)

Visual Basic .NET

J# (允许为 .NET 平台编写 Java 代码的 J Sharp)

FORTRAN

Pascal

COBOL

PERL

Python

Eiffel

事实证明,C# 已经成为经验丰富的 Java 开发人员和那些 .NET 平台新手的普遍选择,因为它与 Java 编程语言有许多相似点。J# 提供了一个 Java 语言子集,它可以编译成 MSIL 并在 CLR 上运行。但是,不管使用哪一种语言,编写完代码后,编译器都将其转成 MSIL。

如果您是一个受虐狂(或者仅乐于用机器代码编程),您可以直接用 MSIL 编写。但是,因为 MSIL 是一种伪机器代码,所以这不是一种完全直观的方法。

内存管理与垃圾回收

CLR 的内存管理的核心是垃圾回收 进程,它类似于 Java 中对应的进程。垃圾回收是一种后台操作,它对提交给内存的对象进行审查,并恢复那些不再需要的对象。垃圾回收分三代,可以恢复短期、中期、长期对象,分别称为 Gen 0Gen 1 Gen 2

所有的新对象都在 Gen 0 堆中开始。垃圾回收算法通过检查堆中是否有应用程序不使用的任何对象而起作用。

许多类为其返回值、临时字符串以及各种其他实用工具类(如枚举器等)创建临时对象。

如果堆中没有足够的空闲内存分配给新对象,垃圾回收循环就从 Gen 0 对象开始。如果内存仍然不够,垃圾回收循环就回收 Gen 1 对象,然后是 Gen 2 对象。当垃圾回收处理了所有代的对象时,就是一个完整的垃圾回收循环。

当垃圾回收循环在运行时,它将所有幸存的对象都提升到下一代。之所以说垃圾回收循环后幸存对象是因为这些对象仍然在使用(可以访问)或者在等待结束。幸存的 Gen 0 对象提升为 Gen 1,而幸存的 Gen 1 对象则提升为 Gen 2。然后垃圾回收处理压缩并移动任何空闲的内存,以保存邻近的空间,将内存碎片的数量降到最低。与下一代相比,每代的垃圾回收循环发生的比例一般是 1:10,例如,进行 10 次 Gen 0 回收就进行一次 Gen 1 回收,进行 10 次 Gen 1 回收就进行一次 Gen 2 回收。

就系统资源来说,较高等级的垃圾回收,花费的开销越高 — 垃圾回收器期望得到更高的小费(开个玩笑)。

托管代码操作

.NET Framework 的第四大功能是托管代码操作。托管代码的定义非常简单 — 托管代码使用 CLR,而非托管代码不用。为了使该定义更严密,应这么说:托管代码完全 在 CLR 内部执行。对非托管组件的调用(服务组件、COM 或 DCOM 对象)超出了 CLR 的范围。因此,CLR 垃圾回收和其他功能不对非托管代码或非托管代码组件进行操作。

实时调试

实时调试 (JIT) 是一种调试在 Visual Studio 外部启动的程序的技术。如果已经启用 JIT 调试,当发生故障时程序就会弹出一个对话框。该对话框会询问是否想调试该程序并且要使用哪一种调试器。

在发生异常时,JIT 调试可以灵活选择调试器。还可以在工作计算机的复制品计算机上调试,这有助于更快地找出编程问题。

异常处理

CLR 处理 .NET Framework 应用程序中的异常,但还提供一些异常管理函数。这其中的主要一个就是 Try/Catch/__Finally,使用这些块可以捕获托管异常和非托管异常。基本的方法就是,在要进行危险操作时使用一个 Try 子句,如果 Try 语句中的函数引起一个异常,就要配对使用一个 Catch 子句。不管异常是否发生都要运行 __Finally 子句。

安全性

CLR 通过使用 XML 格式的配置文件或者 .NET Framework 1.1 配置工具 (Mscorcfg.msc) 的运行库安全策略节点来执行应用程序,从而实现安全性。安全配置文件包含有有关代码组层次和与策略级别相关的权限集的信息。

.NET Framework 配置工具显示有三种主要的安全配置级别:企业、机器或用户。这些级别对应三个安全配置文件(Enterprisesec.config,以及计算机和用户级别的两个独立的 Security.config)。

.NET Framework 配置工具使您可以管理权限集(例如,FullTrust,LocalIntranet,Everything 等等)和代码组,例如,My_Computer_Zone,LocalIntranet_Zone,Trusted_Zone,等等。每个代码组都有一个相关的权限集,例如,Trusted_Zone 会映射到 Internet 权限集。

满足代码组成员条件的程序集接收权限集中相关的权限。权限集可能会包括应用程序是否可以访问 File Open 对话框,是否能够打印,或者可以显示什么样的用户界面。

虽然可以直接编辑安全配置文件,但强烈建议您使用 .NET Framework 配置工具或者代码访问安全策略工具 (Caspol.exe) 来修改安全策略。这样可以确保更改策略时不会破坏安全配置文件。

运行时类型安全检查

.NET Framework 还通过运行时类型安全检查实现安全性。利用类型安全代码,公共语言运行库可以完全将程序集相互分离开来。这样的分离有助于确保程序集相互之间不会有不利的影响,提高了应用程序的可靠性。即使类型安全组件的信任级别不同,它们仍可以在同一个进程中安全地执行。

类型安全代码只能访问授权其访问的位置的内存。例如,类型安全代码不能从另一个对象的私有字段读取数值。它只能以明确定义的、允许的方式访问类型。

虽然类型安全验证没有要求必须运行托管代码,但是类型安全在程序集隔离和安全实现方面起着非常重要的作用。如果代码类型不安全,则会产生不希望的副作用。例如,运行时不能防止不安全代码调用本机(非托管)代码并进行一些恶意的操作。当代码类型安全时,运行时的安全实现机制确保了它只有拥有权限访问本机代码时才能访问。

在进行 JIT 编译期间,一个可选的验证进程对被实时编译为本机代码的方法的元数据与 MSIL 进行检查,以验证它们是否是类型安全的。

线程管理

公共语言运行库主要通过 ThreadPool 类支持多线程应用程序。ThreadPool 可以为大多数任务提供自动的线程创建和管理机制。

公共类型系统

公共类型系统 (CTS) 定义了运行库中应用程序和 .NET Framework 如何声明、使用和管理类型,同时也是运行库支持跨语言集成的一个重要部分。正是有了 CTS 才使得大型开发人员团队可以致力于同一个应用,团队中的每个人可以使用 .NET Framework 支持的多种语言中的任何一种进行编程。

CTS 可执行下面的功能:

建立一个框架,可以进行跨语言集成、类型安全并可执行高性能代码。

提供一个面向对象的模型,完全支持多种编程语言。

定义语言必须遵循的规则,这有助于确保以不同语言编写的对象可以彼此进行交互。

托管代码操作通过 CTS 实现类型安全,因此 CTS 确保了所有的基于 .NET 的应用组件可以进行自我说明。然后,.NET Framework 处理托管代码组件间的引用。

全局程序集缓存

安装 .NET Framework 创建一个机器范围的代码缓存,称为全局程序集缓存。全局程序集缓存存储特别指定为计算机上几个应用程序所共享的程序集(可执行文件或库文件)。结合强名称工具,它还能够允许运行具有相同名称的两个或更多个版本的程序集。这样运行时对程序集的选择控制权就比使用 CLASSPATH 语句时大得多。

有两种版本的全局程序集缓存 — MSCORWKS 是工作站版本,它运行在 Windows XP 与任何可以安装 .NET Framework 的桌面操作系统上。MSCORSVR 是 Windows 2003 Server 系列必备的一部分,而它是作为 Microsoft 的其他服务器操作系统上的 .NET Framework 的一个组件安装的。MSCORWKS 对于单用户的基于 .NET 的应用程序运行得最好,但 MSCORSVR 适用于大型、多处理器、多用户的环境。

通常情况下,可以将应用程序的程序集放置在该应用程序的安装目录中。但是,也许会希望多个应用程序使用同一个程序集,这时可以将程序集放置在全局程序集缓存中,而不是将其复制到两个不同的目录中。

在将程序集放置到全局程序集缓存之前,必须利用强名称工具对程序集进行签名。

有几种方法可以将程序集部署到全局程序集缓存中:

利用为全局程序集缓存设计的安装程序。这是推荐使用的方法。

利用称为全局程序集缓存工具 (Gacutil.exe) 的开发人员工具,它是 .NET Framework SDK 的一部分。

利用 Windows 资源管理器将程序集拖入缓存中。

有关将程序集部署到全局程序集缓存中的最佳实践的更多信息,请参阅 MSDN Deploying .NET Framework-based Applications

强名称

通过利用强名称工具 (SN.exe) 对每个代码组件进行数字签名,.NET Framework 提高了安全性。强名称程序集包括程序集的标识 — 其简单的文字名称、版本号和区域信息(如果有的话)— 连同一个公钥与一个数字签名。

通过创建强名称程序集,可以支持全局程序集缓存中的多个具有相同名称的 DLL。而后应用程序只使用其安装的 DLL 版本,解决了普遍存在的 DLL 冲突问题。利用强名称程序集使得同时安装新版本的程序集和旧版本的程序集成为可能,而不会发生冲突。

为了避免对没有强名称程序集的依赖,强名称程序集只能引用其他强名称程序集。

.NET Remoting

.NET Remoting 是 Microsoft 分布式应用程序的新型通信机制,这些分布式应用程序构建于 .NET Framework 之上。.NET Remoting 的功能类似于 J2EE 中的远程方法调用 (RMI)。

.NET Remoting 使得可以轻松构建大范围的分布式应用程序,而不管应用组件是都位于一台计算机上还是分布在全球不同的地方。利用 .NET Remoting,就可以构建使用同一台计算机或者其网络上可访问的任何其他计算机上的其他进程的对象的客户端应用程序。利用 .NET Remoting 还可以与同一进程的其他应用程序域进行通信。

.NET Remoting 提供了一种进程间通信的抽象方法,它将远程对象从特定的客户端或服务器应用程序域和特定的通信机制中分离出来。因此,可以进行轻松、灵活的自定义。可以用另一种通信协议替代某种通信协议,用另一种序列化格式替代某种序列化格式,而无需重新编译客户端或者服务器。另外,远程系统并不采用特定的应用模型。可以从 Web 应用程序、控制台应用程序、Windows 服务程序 — 从几乎任何您想使用的应用程序进行通信。远程服务器也可以是任何类型的应用程序域。任何应用程序可以承载远程对象,并可以将其服务提供给计算机上或者网络上的任何客户端。

为了利用 .NET Remoting 来构建这样的应用程序:其中的两个组件可以跨应用程序域边界进行直接通信,您只需要构建如下几项:

一个远程对象。

一个侦听该对象请求的宿主应用程序域。

一个请求该对象的客户端应用程序域。

即使在复杂的多客户端/多服务器应用中,您也可以这样看待 .NET Remoting。您还必须配置宿主和客户端应用程序以连接到远程的基础结构中,您必须了解远程基础结构带来的生命周期与激活问题。

构建基于 .NET 的应用程序

有几种方法可以编写和构建基于 .NET 的应用程序。最主要的几种方法如下:

利用 Visual Studio .NET 编写和构建应用程序。

利用您喜爱的开发环境和命令行编译器。

利用文本编辑器和命令行编译器。

使用 Visual Studio .NET 2003

Visual Studio .NET 2003 是 Microsoft 的应用开发环境的最新版本,它与 MSDN Library for Visual Studio .NET 一起安装。Visual Studio .NET 完全符合语言中性的方法,使得用不同语言创建互用性项目变得非常轻松。它为不同项目提供内置的模板,这取决于您希望使用的语言。项目类型包括如下的类型:

基于 Windows 窗体的应用程序。

ASP.NET Web 应用程序。

ASP.NET Web 服务。

类库。

控制台应用程序。

Windows 服务。

另外,Visual Studio 还可以将应用程序打包以进行分发,创建 Windows 安装程序包,CAB 文件,以及安装例程。

利用命令行编译器

利用 Visual Studio .NET 创建基于 .NET 的应用程序没有什么要求条件,了解这一点后您也许会非常高兴。另一种方法是利用 .NET Framework SDK 中的命令行编译器,该方法与使用 JAVAC 和 J2SE SDK 创建的方法类似。

您可以从 SDK Web 站点下载英文版的 .NET Framework SDK v1.1

安装 .NET Framework SDK 时,将会创建 %WINDIR%/Microsoft.NET/Framework/versionnumber 目录,这里versionnumber 等于:.NET Framework 1.0 版时为 v1.0.3705,.NET Framework 1.1 版时为 v1.1.4322。在该目录中,可以找到下面的命令行编译器:

用于 C# 应用程序的 CSC.EXE。

用于 Visual Basic 的 VBC.EXE。

用于 J# 的 JSC.EXE。

利用正确的命令行开关运行编译器生成一个或多个程序集,而后 CLR 可以执行这些程序集。通常,程序集是 .exe 或者 .dll 文件。

利用包含在 .NET Framework (SDK) 中的 Ildasm.exe 反汇编程序工具,可以检查 .exe 或者 .dll 文件的内容。

.NET 程序集包含有描述性元数据,例如 Windows 可移植可执行文件头、程序集依赖项以及版本信息。但是,Java 中没有可直接与程序集进行比拟的东西。最贴近的可比拟对象就是 JAR 文件,它包含存储元数据的类,并且可以与其他 JAR 文件进行交叉引用信息而不需要 CLASSPATH 值。

利用全局程序集缓存查找程序集

.NET Framework 不使用类似 CLASSPATH 的变量,而是使用先前提到的全局程序集缓存。每台计算机上都有全局程序集缓存,它既是一个文件夹又是一个注册组件数据库。该文件夹位于 %WINDIR%/ASSEMBLY 下面,并可以用 Gacutil.exe 注册一个程序集。

当在 Visual Studio .NET 中创建安装包时,要包含注册处理并作为安装的一部分。

要查看全局程序集缓存,请完成下面的步骤。

要检查全局程序集缓存

1.

单击 Start,指向 All Programs,指向 Administrative Tools,然后单击 Microsoft .NET Framework 1.1 Configuration(或者 1.0)。就会出现 .NET Configuration 1.1(或者 1.0)管理控制台。

2.

双击左边窗格中的 Assembly Cache 节点。

3.

在右边的窗格中,单击 View List of Assemblies in the Assembly Cache 链接。就会出现已注册程序集列表。

4.

右键单击某个程序集,然后单击 Properties。将显示 Assemblyname Properties 对话框。

Version 值允许同时有多个版本存在,并允许组件,例如可执行文件,调用某特定的 DLL。版本号的格式如下:

MajorVersion.MinorVersion.BuildNumber.Revision 

例如,7.0.5000.0 是一个 Microsoft.VSDesigner 程序集的公用版本号。

Public key token 是进行代码签名后获得的结果,它唯一标识每个程序集。这就确保了应用程序只能加载正确的程序集,防止恶意或者无意替代应用程序的组件。

理解特性

特性是大多数 Microsoft 软件组件的一个特点,例如 COM 中的界面定义语言 (IDL) 界面,因此这些出现在 .NET Framework 中也就不足为奇了。Java 2 SDK 的当前版本不支持特性,尽管拟议中的 Java 2 SDK 1.5 声称支持类似特性的结构。有关详细信息,请参阅:

JSR 175: A Metadata Facility for the Java Programming Language

New Language Features for Ease of Development in the Java 2 Platform, Standard Edition 1.5: A Conversation with Joshua Bloch

.NET Framework 中的特性既有关键字,还有类似标记的元素。在设计时,利用标记来记录类型、字段、文档类和方法。程序集的元数据包含有特性信息。 .NET Framework 中的许多标准命名空间都包含有特性,如果需要,开发人员可以实现他们自己的自定义特性。

特性的一个实例就是 WebMethod。该特性指出,可以将类内的方法作为一项 XML Web 服务调用。如果将 WebMethod 标记放置在方法的开头,然后编译器就会生成额外的信息,以将该方法公开为一项 XML Web 服务。

下面的几行代码简单地说明了这一点。

[WebMethod] 
public String HelloWorld() 
{ 
    ... 
} 

特性可以接受参数,参数是作为标记的一部分。这类似于构造函数类。

[WebMethod(Namespace="http://www.microsoft.com/Interoperability")] 

这将 WebMethod 特性的命名空间属性指定为指定的 URL。

CLR 支持任何语言的特性,但是开发语言格式决定了标记的前缀。

创建 Web 应用程序

在 Java 中,可以利用 JSP 页和 servlet 创建 Web 应用程序。在 .NET 中,可以利用最新的 Active Server Pages (ASP) 成果即 ASP.NET 来创建。通常情况下,ASP.NET 应用程序将运行在Internet 信息服务 (IIS) 之上,但是这一点并不是一条非常严格的要求。例如,也可以在诸如基于 Apache 2.0 的 Enterprise Ready Server 的平台上运行 ASP.NET 应用程序。

ASP.NET 比 JSP 的功能有所改善,具有诸如代码隐藏和事件驱动 Web 控件的功能。为在 JSP 中实现等同的功能,需要脚本语言和一套额外的工具。根据既熟悉 Java 又熟悉 .NET 的开发人员的体验,ASP.NET 比 JSP 更强大,它比早期的 ASP 更好。JavaServer Faces 的引入只是为了弥补 JSP 的不足。

ASP.NET 应用程序往往有图形化前端,因此开发人员往往偏爱使用 Visual Studio .NET 来创建和编辑 ASP.NET 页。另外一种免费的集成开发环境 (IDE) 是 Web Matrix,可以从 ASP.NET Web 站点下载。

可以用 .NET Framework CLR 支持的任何语言创建 ASP.NET Web 应用程序。这就为用任何语言编程提供了灵活性,甚至可以通过组合团队开发人员用不同语言构建的元素来创建Web 站点。

承载组件

.NET Framework中没有直接与 EJB 对等的工具。但是,有三种主要的技术可用来为企业应用程序提供寄宿的组件:

作为一项 Windows 服务而运行。

通过 IIS 承载。

利用组件服务。

作为一项 Windows 服务而运行

Windows 服务(或者叫 NT 服务)是运行在计算机上的系统级进程,它与登录的用户无关。典型的服务包括操纵系统的功能、计划程序、病毒扫描程序、数据库引擎和网络组件。

可以利用 Visual Studio .NET 中的模板来获取 .NET 程序集,并作为一项服务来运行。这样就生成一个应用程序,只要计算机在运行,该应用程序就也在运行。

作为服务运行的应用程序需要处理其自身的网络配置。特别是,这些应用程序应当在域帐户下运行,而不是在本地机器帐户上运行。这是因为本地机器帐户只拥有本地计算机的权利。

通过 IIS 承载

Internet 信息服务提供了一个可以承载表示层和业务层组件的框架。利用一个与程序集相关的配置文件,可以在 IIS 内为如下的几项配置支持:

部署程序集。

处理输入连接。

支持协议。

实现连接池。

配置安全性。

另一种方法是构建自己自定义的框架来承载程序集。但是,这是一项非常耗时与麻烦的工作。

利用组件服务

在 IIS 上承载程序集非常简单方便,但是它不能提供 EJB 所具有的全部功能。组件服务(或者称作 COM+)提供了另外的功能,例如:

回收

状态管理

事务支持

方法级安全性

记录日志

模拟

消息队列支持

.NET 开发人员可以通过组件服务管理工具或者利用可编程特性来设置 COM+ 属性。

虽然有许多第三方实现的方法,但是在 .NET 中没有与容器托管持久性 (CMP)、容器托管关系或者 EJB-QL 对等的工具。Visual Studio .NET 具有自动生成 SQL 语句以及将数据库表拖放到 IDE 中的工具。

支持 Web 服务

Microsoft 在支持 Web 服务方面已经花费了相当多的精力。ASP.NET Web 服务是实现基于 .NET Framework 的 Web 服务的首选技术。

在 HTTP 中,ASP.NET Web 服务利用 SOAP 支持服务请求。ASP.NET Web 服务为 Web 服务自动生成 WSDL 和发现文件 (.disco)。可以利用 ASP.NET Web 服务来实现一个 Web 服务侦听器,它可以访问作为 COM 组件或者托管类而实现的业务外观。 .NET Framework SDK 还提供生成代理类的工具,客户端应用程序可以利用代理类访问 Web 服务。

与数据库连接

.NET Framework提供 ADO.NET (以前称作 ActiveX Data Object),作为与数据库连接的框架。从架构师的角度来看,ADO.NET 表示的是可以在 .NET Framework 中用来构建数据访问类的抽象设计概念。从开发人员的角度来看,ADO.NET 表示的是在 .NET Framework 内实现的具体类,.NET Framework 随后可以用这些类进行数据访问。

ADO.NET 提供的功能类似于 JDBC 和 JDO 中实现的功能。

对于 ADO.NET 来说,有几项主要的设计目标:

明确、分解的对象模型— ADO.NET 是一种简单易用的对象模型,开发人员完全有权决定如何控制数据源的连接、命令的执行和数据的操作。

断开数据缓存模型N 层编程与 XML Web 服务体系结构要求应用程序可以以一种断开的、松耦合的方式来参与。ADO.NET 提供了一种综合的缓存数据模型,以在应用程序或服务之间封送处理数据,然后优化更新原来的数据源。

XML 支持 — XML 是构建可互操作应用程序与可靠数据处理模型的关键。XML 支持直接包含在 .NET Framework 中,ADO.NET 通过关系的方式或者本机 XML 的方式与 XML 进行无缝交互来使用该实现。

可以将 ADO.NET 体系结构分成两个逻辑片段:命令执行与缓存。命令执行需要的功能包括连接、执行和读取结果等,.NET 数据提供程序支持这些功能。DataSet 功能是处理结果的缓存。

实现集合

集合 是一组可以归类在一起的相似类型对象。这对等于 J2EE 平台上的java.util.collections

可以将任何类型的对象分到同一个类型为 Object 集合中,以利用编程语言中固有的结构。例如,C# foreach 语句期望集合中所有的对象都是同一种类型。

但是,在类型 Object 集合中,装箱和取消装箱或转化这样的额外处理会影响集合的性能。一般情况下,当存储或恢复类型为 Object 的集合中的一个值类型时会发生装箱和取消装箱。

强类型集合,例如 StringCollection,如果元素的类型就是集合预期的类型(例如从 StringCollection 存储或恢复字符串),那么就可以避免这些影响性能的因素。另外,强类型集合会自动验证每一个添加到集合中的元素的类型。

可以将 collections 类分成三种类型:

一般集合— 常见的数据集合变量,例如哈希表、队列、堆栈、目录和列表。

位集合 — 其元素是位标志的集合。它们与其他集合略有不同。

专用集合 — 具有特殊目的的集合,通常处理特定类型的元素,例如 StringDictionary

访问目录服务

.NET 中的访问目录服务的通常含义是:利用轻量级目录访问协议 (LDAP) 或者 Active Directory 服务接口 (ADSI),即 JNDI 的对等物,连接到Active Directory。

Microsoft 在 Wldap32.dll — 也称作“LDAP?C”或“C-binding LDAP”中实现 LDAP API。 LDAP 编写的应用程序只与 LDAP 目录服务是兼容的,尽管 Active Directory 也完全支持 LDAP API 进行目录访问。

为 Active Directory 主要推荐的 API 是 ADSI。ADSI 位于 LDAP 的顶端,还可以通过 LDAP 提供最简单的访问 Active Directory 的方式。通过公开以 COM 对象的形式存储在目录中的对象,本机 ADSI 允许访问 Active Directory。然后就可以利用 COM 接口中的方法操作目录中的对象。

ADSI 提供程序 包含特定命名空间的 ADSI 对象实现,最重要的一个就是 ADSI LDAP 提供程序。通过实现所需的接口,ADSI 提供程序将这些接口转换为特定目录服务的 API 调用。

ADSI LDAP 提供程序在 ADSI 客户端运行,访问 Active Directory 或者其他的 LDAP 目录服务。ADSI LDAP 提供程序可以与支持 LDAPv2 或更新版本的任何 LDAP 服务器协同工作。

有关 LDAP API 和 LDAP 编程的更多信息,请参阅 Web 资源页上的链接 Microsoft Platform SDK

反射

反射 允许编写代码以在运行时动态检查数据类型或者对象。可以获得它的一系列方法、接口甚至是类级变量。反射甚至可以允许通过调用动态发现的方法或者给动态发现的变量赋值来与对象进行交互。

利用反射,可以创建对象浏览器、列举与记录方法的应用程序,甚至是高度可配置的、元数据驱动的应用程序,这些应用程序根据表或者 XML 文件中的指令创建对象与调用方法。这些都是在基于 .NET 的应用中可以使用的强大功能。

要注意,反射还会进行具有潜在危险的操作。可以利用反射来调用在作用域中是 Private 的方法。还可以直接给对象的变量赋值,而并不调用任何业务逻辑。反射提供了以非常危险的方式误用对象的工具。但是,可以利用这些功能来创建非常强大的代码,例如根据将对象的变量名称与表中的列名匹配的元数据,创建从 DataSet 将数据加载到对象中的代码。

J2EE 基本原理(针对 .NET 开发人员)

如果您是一位 .NET 开发人员并想了解 J2EE 平台的组件和功能,那么您可以从这里着手。

Sun Microsystems 开发的 Java 既是一个平台,又是一种编程语言。目前 Java 平台有三个版本:

J2SE (Java 2 Standard Edition)

J2EE (Java 2 Enterprise Edition)

J2ME (Java 2 Micro Edition)

“Java”这个术语通常指的是 J2SE 具有的功能。需要企业版功能的领域要包含 J2EE。

Java 2 Platform, Enterprise Edition 或者 J2EE 是一套相互联系的规范,它允许开发人员创建基于服务器的多层应用程序。因此,与 Microsoft 的 .NET 不同,J2EE 是一个标准而不是一个产品。J2EE 规范包括一系列可以下载的 Adobe PDF 文件,用来说明应用程序协议与应用程序运行所在的容器结构。

和 .NET一样,J2EE 使您可以只关注编写业务逻辑而不是企业框架自身,使得编写分布式企业应用程序变得更轻松。J2EE 提供允许运行应用程序的“基础结构”,否则编写这些会很乏味与耗时。

发布时,J2EE v1.3 是最新的发布版本,而 v1.4 还处于最终的草案阶段。

因此,J2EE 平台与 Microsoft .NET 的观点类似,两种平台所贯穿的主题是相同的。但是理解二者的本质区别非常重要。Java 与 Microsoft .NET 主要在三个方面不同,它们是:

操作系统支持

语言支持

执行方法

从一开始,设计 Java 时就尽可能使它工作在各种操作系统上。因此,Java 代码可以运行在多种环境中,例如:

Windows

UNIX

Linux

MacOS

BeOS

但是,Microsoft .NET 只能在 Windows 上运行。

Rotor 是运行在 FreeBSD 上的 .NET Framework 版本。但是,这更多的是进行学术研究,而不是一个实用的实现方案。

语言支持包括语言、格式以及创建程序使用的语法。编写 Java 应用程序只能用 Java 编程语言。对于 .NET,则可以选择任何支持 .NET Framework 的语言。

两种平台在运行应用程序时也有重要的不同点。当基于 .NET 语言构建项目时,输出是 MSIL 代码,它是运行时 JIT 编译器编译的代码。

为了部署一个 Java 程序,要编译应用程序以创建 Java字节码。运行在目标操作系统之上的 JVM 对这些字节码进行解释,生成相关的指令。

同时,Java JIT 编译器的工作方式与 .NET Framework 组件的类似。

理解 Java 平台

Java 平台有两个主要组件。它们是:

Java 运行时环境 (JRE)

Java 语言与格式 (API)

JRE 的主要组件是 Java 虚拟机,或者叫 JVM。JVM 的作用是为操作系统将 Java 字节码解释成本机指令。但是,JVM 还提供许多类似于 .NET CLR 的功能。JRE 也包括 Java 类库。

J2EE 框架内还有过去十年中发展的其他组件。它们是:

Java Server Pages (JSP)

Server side API 或者 servlet

Enterprise Java Beans (EJB)

Java Naming and Directory Interface (JNDI)

Java Message Service (JMS)

Java API for XML-based RPC (JAX-RPC)

J2EE Connector Architecture

J2EE Management Model

J2EE Deployment API

Java Management Extensions (JMX)

J2EE Authorization Contract for Containers

Java API for XML Registries (JAXR)

Java Transaction API (JTA)

Common Object Request Broker Architecture (CORBA)

JDBC data access API

这些组件大部分在 .NET Framework 或 Windows 中都有与之对应的组件。例如,JMS 提供基于消息的事务的支持,它映射到 System.Messaging 命名空间。

由于 J2EE 是一种规范,而非一种产品,许多供应商在 Sun 的许可下创建了他们自己的实现,这些供应商包括:

Sun (Sun ONE Application Server)

IBM (WebSphere)

BEA (WebLogic)

还有几种开放源代码实现,最著名的是 JBoss。有关更多信息,请参阅 JBoss Web 站点 http://www.jboss.org/

实现 Java SDK

和 .NET Framework 一样,Java 有一个软件开发工具包,来帮助您创建、编译 Java 应用程序。Java SDK 已经修改过多次,您可以从 Sun 的 Java Web 站点下载 Java 2 SDK,Standard Edition 1.4。

其他的供应商在许可下,已经生产出了他们自己的 Java SDK 实现。和 J2EE 应用程序服务器一样,这些供应商包括 IBM 与 BEA,还有一些开放源代码实现。直到 1.1.4 版时,Microsoft 才有了实现。

Java 2 SDK 包含有类库,在创建自己的 Java 源代码以及构建和执行这些应用程序的编译器和二进制文件时可以使用这些类库。SDK 的 bin 目录中包含一个 Javac.exe 文件,可用来将 Java 源代码(*.java 文件)编译成 Java 字节码(*.class 文件)。但是,和 .NET 应用程序一样,只有最顽固、保守的工作才完全从命令行执行,而大多数工作使用基于 GUI 的 IDE 来创建与编译 Java 应用程序。

构建 Java 应用程序

当用 Java 编译器编译 Java 类时,Java 中的每个类就生成一个单独的 .class 文件,.class 文件是标准的编译单元。然后 JVM 就可以按照下面的格式执行该 .class 文件:

java myapp.class 

但是,.class 文件不是与 .NET 中的程序集完全对应,这是因为 .NET 程序集既是执行的单元又是分发的单元。Java 开发人员利用 Java 存档 (JAR) 文件可以创建包含多个 .calss 文件的可发布应用程序。尽管 JAR 文件可以包含任何类型的文件并拥有一个内部目录结构,就像一个 ZIP 文件,但一个基本 JAR 文件就是一个已编译的 Java 类集合。可以利用 SDK 的 /bin 目录中的 Jar.exe 文件来添加、列出 .class 文件或从 JAR 文件解压出 .class 文件。

可以用 JVM Java.exe 文件来执行 JAR 文件。格式为:

java jar myapp.jar 

只利用本机操作系统命令和 Java 2 SDK 提供的基本工具就可以构建与部署一个完整的 J2EE 应用程序,如果您真希望这样做的话。但是这种方法非常乏味并且容易出错。相反,开发人员经常使用的构建工具,如 ANT,它是 Apache Jakarta 项目的一部分。 ANT 是一种与平台无关的构建工具,它自动编译、打包和部署应用程序。它利用 XML 构建文件来决定编译和部署项目需要完成的任务。

有关更多 ANT 的信息,请参阅 Apache ANT Web 站点

定位与共享类

Java 平台没有与全局程序集缓存对等的东西。但是,应用程序可能仍需要引用或共享其他的类。Java 中,利用名称为 CLASSPATH 的环境变量来完成此项工作。这类似于 Autoexec.bat 启动文件中的 PATH 语句,或者 Windows 中的 System Profile 属性。

默认的类路径就是当前的目录。如果您愿意,可以将环境变量 CLASSPATH 设置为一个或多个不同的目录。这样做时,必须明确将该路径包含到主要的 Java 2 SDK 工具 JAR 以及当前的目录中。因此,运行于 Windows 上的 Java SDK 1.3 版中的简单 CLASSPATH 语句如下所示:

SET CLASSPATH = .;%J2EE_HOME%/LIB/J2EE.JAR; 

如果应用程序需要其他的类或者 JAR 文件,则在运行该应用程序之前就要修改 CLASSPATH 变量。按照如下所示引用当前的 CLASSPATH 变量就可以做到这一点。

SET CLASSPATH = %CLASSPATH%;C:/OTHERAPP/RESOURCES.JAR;C:/OTHERAPP/CLASSES 

这样就将该新目录添加到了现有的 CLASSPATH 中,因此当 Java 应用程序加载和要求某个类时,应用程序还要搜索目录 C:/OtherApp/Classes 中的所有类或者搜索 JAR 文件 C:/OtherApp/Resources.jar。

Javac.exe 编译器和 Java.exe 执行工具都可以接受参数,以包含或修改 CLASSPATH 变量。Java IDE 也允许您包含 CLASSPATH 语句。通过将这些库作为 JRE 的扩展安装,也可以不设置 CLASSPATH 就能将库自动添加到类搜索序列中。

注如果 Java 应用程序生成 ClassNotFoundException,几乎就可以确定这是因为 CLASSPATH 语句中没有所需的库。

实现其他环境变量

Java 应用程序使用的环境变量往往比基于 .NET 的应用程序使用的环境变量多。这是因为 Java 应用程序可以在多种操作系统上运行,所以它们需要能够处理不同的环境。环境变量提供了一种简单的方法,确保设置与控制配置以及应用程序执行路径的一致性。

表 2.1:公共环境变量
变量名称作用

JAVA_HOME

Sun Java SDK 的安装位置

J2EE_HOME

Sun J2EE SDK 的安装位置

ANT_HOME

ANT 的主目录

PATH

Windows PATH 语句

使用 Java 集成设计环境

几家供应商生产了 IDE 包来协助进行创建和编辑工作,范围从增强的文本编辑器到类似于 Visual Studio .NET 的功能齐全的包。有些是需要付费的包,其他的是免费的。这里的例子包括:

Sun One Studio

JCreator

Borland JBuilder

Java GUI Builder

JPad Pro

CodeGuide

NetBeans

AnyJ

虽然可以利用 Visual Studio .NET 中的 Visual J# 来创建与编辑 Java 应用程序,但是 J# IntelliSense 技术只适用于 Java SDK 1.1.4 及以上版本的 Java API 类,并且需要利用 Javac.exe 从命令行来编译应用程序。

所有的 IDE 包都允许在 IDE 环境内编译应用程序。另一种方法是像 Visual Studio 一样,可以从命令行编译应用程序。

创建 Web 应用程序

对于表示层组件,Java 在 .NET 体系结构中使用 ASP.NET 的地方实现 JSP。JSP 提供了开发 Web 应用的服务器端技术,而且 JSP 页是 HTML 与 Java 代码的混合体。

基于 Java 的 Web 应用利用了动态编译 JSP 页与 servlet 的概念。servlet 就是一个 Java 编程语言类,它扩展了承载通过请求-响应编程模型访问的应用程序的计算机的功能。也可以将 Java 的 servlet 看作是为用户请求提供动态内容的可移植组件。

第一眼看上去,JSP 和 servlet 非常相似,两者都产生动态的内容。可以用 Java 编程语言在 JSP 页或者 servlet 内创建任何脚本元素。另外,在运行时 JVM 将 JSP 编译成 servlet,因此二者使用的是同一种引擎。 但是,开发 servlet 需要编写 Java 类,因此比开发 JSP 需要更高的编程技巧。可以将 servlet 看作是包含有 HTML 内容的 Java 代码。

和 servlet 一样,JSP 为用户提供动态的内容,但比 servlet 的抽象度更高。可以将 JSP 看作是包含有动态 Java 代码的静态 HTML。

可以将 JSP 和 servlet 寄宿在多种环境上。这包括免费提供的环境如 Apache Tomcat,以及大型的商业软件与供应商支持的实现。

为实现基于 JSP 的应用程序,可以利用 Java IDE 来设计应用程序。几种 IDE 都包含有实时编辑 JSP 页的工具,可以预览到任何更改图形或控件后的效果。

目前 JSP 规范的版本号为 v1.2,servlet API 的版本号是 v2.3。

为了部署 Web 应用程序,要将它们打包到一个称为 Web 应用程序存档 (WAR) 文件的可部署单元中。这类似于将 Java 应用程序打包到 JAR 中。然后就可以轻松地将该 WAR 文件部署到 Web 服务器上。

承载组件

JSP 页 和servlet 的主要功能就是通过表示层中的浏览器与用户进行交互。但是,在业务层中执行业务规则时需要利用称为 Enterprise Java Beans (EJB) 的组件。EJB 是 COM+ 组件或托管代码组件的对等组件,并可提供下列服务:

维护状态

事务性支持

方法级安全

记录日志

模拟

消息队列支持

EJB 有三种形式:

会话 bean

实体 bean

消息驱动 bean。

会话 bean 管理业务逻辑,例如定义客户关系管理系统运营的规则。会话 bean 可以是无状态的,或者可以维护状态,在对象的生存期内将客户端约束在会话 bean 上。通常会话 bean 提供某种服务,例如执行某个任务(如对客户端进行身份验证)。

实体 bean 代表的是持久性存储区中的对象。实体 bean 的每一个实例都对应数据库表中的一行数据。有两类实体 bean:容器托管持久性 (CMP) bean,由容器托管,而 bean 托管持久性 (BMP) bean 自己管理持久性。

对于 CMP 实体 bean,容器利用映射文件托管 bean 和数据库字段之间的映射。该映射文件通常将这些映射保存为 XML 部署描述符。容器托管所有与数据库的通信。与 BMP 相比,CMP具有以下优点:

容易配置

容易维护

不需要数据库代码

由于抽象度较高,CMP 的主要缺点是它的性能差。但是,J2EE 规范已经引入了一些新功能,例如虚拟访问器,它提高了使用 CMP 的 bean 的性能。

对于 BMP 实体 bean,开发人员负责编写所有的 JDBC 代码,以在 bean 和 数据存储区之间传输数据。BMP 要求开发人员编写的与数据有关的代码比 CMP 的还要多得多,但是使用 BMP 仍然有几个很好的理由:

灵活性更大

性能更好

可以与多个数据库源连接

Java 开发人员将会利用 CMP 与标准数据库(例如 Oracle)或者在每秒交易量小的地方进行连接。在需要数据访问速度快或需要开发人员灵活地与非标准数据库如 LDAP 目录连接的场合,正是 BMP 的用武之地。

需要将消息驱动 bean (MDB) 与 JMS API 结合使用,以异步处理消息。消息驱动 bean 就是 JMS 消息的使用者。客户端不直接访问 MDB,他们将 JMS 消息发送到侦听 MDB 的目标。这样就能够重用 MDB,并且还意味着开发人员不必担心到何处获得消息。

使用 MDB 的两大优势是,MDB 可以并行处理用户的请求,与使用非基于消息的实体 Java bean 的串行调用相比,响应速度较快。并且,在搜索多个数据源时,MDB 实现可以担保对用户的响应时间。

构建企业 JavaBean

当构建企业 JavaBean 时,开发人员必须要创建该 bean 的实现类以及许多接口。客户端通过开发人员在 bean 接口中定义的方法来访问会话和实体 bean。这些接口决定了客户如何与 EJB 进行通信。消息驱动的 bean 和实体与会话 bean 是有区别的,这是因为它们没有接口,它们只包含一个 bean 实现类。

实体或会话 bean 上定义的接口取决于一个关键因素:是远程访问还是本机访问该 bean?

远程客户端的情况为:

在与客户端独立的 JVM 中运行的应用程序或组件(尽管该应用程序不要求必须在独立的 JVM 中运行。)

在不同的计算机上执行的应用程序或组件。

Web 组件,例如 servlet、客户端应用程序,或者另一个 EJB。

客户端不知道(或者需要知道)EJB 位置的场合。

如果 EJB 服务于远程客户端,开发人员必须创建两个接口:一个远程接口与一个本机接口。远程接口定义特定于 bean 的业务方法,例如 AuthenticateCustomer。本机接口定义管理 bean 实例的方法。例如,会话 bean 拥有创建与移除 bean 实例的方法。实体 bean 也包含有定位的方法。定位方法允许客户端定位实体 bean,例如,findByPrimaryKey

如果有下面几种情况,则为本地客户端:

客户端组件或应用程序在与 EJB 相同的 JVM 中执行。

客户端可以是 Web 组件或者 EJB。

EJB 的位置对于客户端来说是不透明的。

如果要求 EJB 为本地客户端服务,也需要创建两个接口,一个本地接口与一个本地本机接口。本地接口定义 bean 的业务方法,定义的方法类似于远程接口。本地本机接口类似于远程本机接口,这是因为它定义操作 bean 实例的方法以及定位的方法。

通常,本地客户端调用本地接口的方法比远程调用的效率更高。在典型的 J2EE 应用程序中,会话 bean 提供远程客户端访问,但是实体 bean 通常情况下提供本地客户端访问。使用 CMP 的实体 bean 几乎总是利用本地访问。

部署应用程序

构建与部署 J2EE 应用程序涉及许多步骤,从而确保部署了应用程序工作所需的所有内容。除了包含 EJB 或者其他类的 JAR 文件,应用程序可能还需要 WAR 文件。WAR 文件就是具有 Web 应用程序所需结构的 JAR。最后,企业存档文件 (EAR) 可以包含 WAR 与填充有 EJB 和其他内容的 JAR。

可以利用部署描述符来配置部署设置,它是具有定义的结构的 .XML 文件。部署描述符指定设置,例如安全性、事务性支持以及日志记录,它告知应用程序服务器如何部署与支持应用程序中的组件。此外,这些设置与组件服务中的设置是关联的。有些部署描述符设置是 J2EE 规范的一部分,但是其他的与应用程序服务器有关,并特定于供应商。

.NET 和 J2EE 的特性对比

表 2.2 是 .NET 与 J2EE 特性与功能的对比。但是,每种平台的背景组成不同,所以直接比较 .NET 与 J2EE 有时会不合适。例如,MSMQ 是一种产品,而 JMS 是一个 API。因此,不能简单地去掉某个组件而代之以其他平台的对等组件。

表 2.2:.NET 与 J2EE 的功能对比
特性或服务Microsoft .NET 元素J2EE 元素注释

技术类型

产品

标准

-

中间件供应商

Microsoft 及其合作伙伴

50 多个供应商

-

客户端 GUI

Windows 窗体环境

AWT/SWING

SWING/AWT 是 J2SE 的一部分

Web GUI

ASP.NET

JSP

-

Web 脚本

ISAPI

HttpHandler HttpModule

Servlet

Filter

-

Web 应用程序宿主

Internet Information Server

多种(取决于供应商的实现)

J2EE 的示例包括Apache Tomcat

解释程序

CLR

JRE

-

服务器端业务逻辑组件

.NET 类或者服务组件 (COM+)

EJB Session Beans

-

服务器端数据组件 1

具有 DB 逻辑的服务组件

有 Bean 托管持久性的 EJB

-

服务器端数据组件 2

ADO.NET 数据集

有容器托管持久性的 EJB

只是一个近似的对等物

目录访问

通过 LDAP 实现 Active Directory 服务接口 (ADSI)

通过 LDAP 实现 Java 命名与目录服务 (JNDI)

LDAP 的兼容性使得目录服务之间的切换非常简单。

远程调用

.NET Remoting

RMI-IIOP

-

数据访问

ADO.NET

JDBC, SQL/J, JDO

-

消息处理

Microsoft 消息队列

JMS

Microsoft 消息队列是一种产品。

JMS 是一种规范,因此需要底层实现。

事务性支持

COM+/分布式事务控制器 (DTC)

JTA

-

 

小结

本章为 Java 开发人员概要介绍了 .NET,还为 .NET 开发人员概要介绍了 Java。比较了每种平台的特性,说明了不同环境中的对等组件。还说明了不同平台如何处理共同的编程问题以及每种平台使用的解决方案。

参考资料

有关 .NET Framework 的信息,请参阅

http://msdn.microsoft.com/netframework/

有关用任何支持语言编程的开发环境 — Visual Studio .NET 的信息,请参阅

http://msdn.microsoft.com/vstudio/

有关支持分布式环境与 .NET Framework 的操作系统 — Windows Server System 的信息,请参阅

http://www.microsoft.com/windowsserversystem/default.mspx

下载 .NET Framework 1.1 版

http://msdn.microsoft.com/netframework/downloads/howtoget.aspx#section3

- 或者 -

从 Windows 更新服务 Web 站点

http://windowsupdate.microsoft.com/ 下载

有关 Java 2 SDK 1.5 支持类似特性的结构的更多详细信息,请参阅 JSR 175: A Metadata Facility for the Java Programming Language

http://www.jcp.org/en/jsr/detail?id=175

- 或者 -

Ease of Development in the Java 2 Platform, Standard?Edition 1.5:A Conversation with Joshua Bloch

http://java.sun.com/features/2003/05/bloch_qa.html

有关将程序集部署到全局程序集缓存中最佳实践的更多信息,请参阅Deploying .NET Framework-based Applications

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/DALGRoadmap.asp

从 SDK Web 站点上下载英文版 .NET Framework SDK v1.1

http://www.microsoft.com/downloads/details.aspx?familyid=9b3a2ca6-3647-4070-9f41-a333c6b9181d&displaylang=en

从 ASP.NET Web 站点上下载另一种免费集成开发环境 Web Matrix

http://www.asp.net/webmatrix

有关 LDAP API 和以 LDAP 编程的更多信息,参见 Web 资源页上的 Microsoft 平台 SDK

http://windows.microsoft.com/windows2000/reskit/webresources

要下载 Java 2 SDK,Standard Edition v 1.4,请参阅 Sun 公司的 Java Web 站点

http://java.sun.com/

有关 ANT 的更多信息,请参阅 Apache ANT 的 Web 站点

http://ant.apache.org/

转到原英文页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值