Java EE架构设计与开发实践
上QQ阅读APP看书,第一时间看更新

1.1 Java EE简介

我们知道,Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的HotJava浏览器(支持Java Applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java Applet。Java 2平台包括标准版(J2SE)、企业版(J2EE)和小型版(J2ME)3个版本,如表1-1所示。每个版本名称中都带有一个数字“2”,这个“2”是指Java 2,自从Java 1.2发布后,Java改名为Java 2(不过人们平时仍然称为Java)。

表1-1 Java的3种版本

Java 5.0版本后,J2EE、J2SE、J2ME分别更名为Java EE、Java SE、Java ME。本书主要是面向Java EE 5.0以上版本进行详细介绍。

1.1.1 什么是Java EE

Java EE是Sun公司(2009年4月20日Oracle公司将其收购)为企业级应用推出的标准平台。它为应用程序组件定义了4种容器:Web、Enterprise JavaBean(EJB)、应用程序客户机和Applet,能够帮助开发和部署可移植、健壮、可伸缩且安全的服务器端Java应用程序。Java EE是在Java SE的基础上构建的,提供Web服务、组件模型、管理和通信API,可以用来实现企业级的面向服务体系结构(Service-Oriented Architecture,SOA)和Web 2.0应用程序。

与Java不同,Java是一门编程语言,而Java EE是一个标准中间体系结构,旨在简化和规范分布式多层企业应用系统的开发和部署。Java EE将企业应用程序划分为多个不同的层,并在每一个层上定义对应的组件来实现它。典型的Java EE结构的应用程序包括4层:客户层、表示逻辑层(Web层)、业务逻辑层和企业信息系统层。

客户层可以是网络浏览器或者是桌面应用程序。

表示逻辑层(Web层)、业务逻辑层都位于应用服务器上,它们都是由一些Java EE标准组件JSP(Java Server Page)、JSF(Java Server Face)、Servlet、EJB(Enterprise JavaBeans)和Entity等来实现,这些组件运行在Java EE标准的应用服务器上,以实现特定的表现逻辑和业务逻辑。

企业信息系统层主要用于企业信息的存储管理,主要包括数据库系统、电子邮件系统、目录服务等。Java EE应用程序组件经常需要访问企业信息系统层来获取所需的数据信息。

Java EE体系架构的实施可显著提高企业应用系统的可移植性、安全性、可伸缩性、负载平衡和可重用性。

1.1.2 Java EE的新特性

目前最新版本Java EE 7扩展了Java EE 6,利用更加透明的JCP和社区参与来引入新的功能,如图1-1所示,主要包括加强对HTML 5动态可伸缩应用程序的支持、提高开发人员的生产力和满足苛刻的企业需求。

图1-1 Java EE新特性

Java EE 7新特性如下。

1.提高开发人员的生产

从Java EE 5开始,重心就一直放在提高开发人员的生产力上。这对于Java开发者来说非常重要,因为这使得使用Java EE进行开发更加便捷,更重要的是能够满足快速管理和生产的需求。鉴于此,Java EE 7大大提高了开发人员的生产力。首先,减少了编写大量核心业务逻辑所需要的样板代码。其次,该平台引入更多的注释POJOS来降低XML配置的复杂性。最后,Java EE 7使用更紧密集成的技术,提供一个更加无缝的开发体验。

2.加强对HTML 5动态可伸缩应用程序的支持

HTML 5是包括HTML、JavaScript和CSS3在内的一套技术组合,其加快了开发人员创建高度互动的应用程序的步伐。开发出的应用程序都是以高度互动的方式提供实时的数据,如聊天应用程序、比赛实况报导等,并且这些应用程序只需要编写一次,就可以应用在桌面、移动客户端等不同设备上,具有非常好的跨平台性。这些高度动态的应用程序,使得用户可以在任何地点任何时间进行访问,从而对服务器端向客户端传送数据的规模提出了更高的要求。Java EE 7在更新现有技术如JAX-RS 2.0、Java Server Faces 2.2和Servlet 3.1 NIO基础上,又借助新的应用技术WebSockets和JSON处理,为支持动态应用程序HTML 5奠定了坚实的基础。

3.满足苛刻的企业需求

为更好地满足企业的需求,Java EE 7提供了许多新功能:

❑ 细化批处理作业,形成可管理的区块,以实现不间断的OLTP性能。

❑ 简化多线程并发任务的定义,以提高可扩展性。

❑ 提供具有选择性和灵活性的事务应用程序等。

Java EE 7开发的开放性,使得Java社区、供应商、组织和个人都能参与其中。19个来自世界各地的用户组,包括来自北美、南美、欧洲和亚洲,都参与了“采用JSR”计划,提供了宝贵的反馈意见和代码示例以验证Java规范(JSR)的API。在最新发布的Java EE平台中都大大简化了访问集装箱服务的API,同时大大拓宽了服务范围。Java EE 7继续秉承了简化性和高效性的趋势,并进一步拓宽了平台范围。

4.减少冗余代码

Java EE 7一直在致力于减少在核心业务逻辑代码运行前必须执行的样板代码。减少样板代码的3大核心区域是默认资源、JMS 2.0和JAX-RS客户端API。默认资源是一个新的功能,要求平台提供商预配置一个默认的数据源和一个默认的JMS连接工厂。这可以让开发人员直接使用默认的资源而无须进行额外的定义。JMS 2.0在可伸缩性和可移植性上经历了重大的改进,减少了冗余代码,已运用在无数的产品部署上,事实证明其是一个良好的规范,能够较好地满足企业的需求。

5.更多带注释的POJO

通过注释Java EE使开发人员更专注于Java对象的编程而无须关注烦琐的配置。

CDI现在默认情况下已不需要使用beans.xml文件就可以直接使用。开发人员可以不需要任何配置而是简单的使用 @Inject来注入任何Java对象。包括新的资源注释@JMSDestinationDefinition和 @MailSessionDefinition,使得开发人员在源代码中就可以指定元数据资源,简化了DevOps体验。

6.更紧密集成的平台

Java EE 6引入了Managed Beans 1.0,第一步朝着EJBs、JSF Managed Beans和CDI beans发展。Java EE 7继承了这一点,例如,对JSF Managed Beans进行了改进以更好支持CDI Beans。Java EE 7为平台引入了易用的EJB容器管理事物,使用基于CDI拦截器的解决方案来保证事务可用在CDI managed beans和其他Java EE组件中,把注释@Transactional应用到任何CDI bean或者任何支持事务的方法中。

Bean Validation在Java EE 7中使用广泛,现在可以用于方法级别的验证,包括内置和自定义的约束。约束可被应用于方法的参数以及返回值。约束也可以使用灵活渲染和违反约束的字符串格式的Java EE的表达语言。

Bean Validation也延伸到JAX-RS 2.0。注释约束可以应用到公共构造函数的参数、方法参数、字段和bean的属性。此外,它们还可以修饰资源类、实体参数和资源的方法。例如,约束可以通过 @ POST和 @ PUT应用于JAX-RS方法参数来验证表单提交的数据。

7.通过精简现有技术来简化Java EE

Java EE 7中新增加了许多新的特性,有些老的特性和功能已经被更简单的特性所替代或直接弃用。Java EE 6为过时技术的弃用和功能的修剪引入了一个正式的流程,以下的API在Java EE 7中已成可选,但在Java EE 8中将会被移除。

❑ Java EE Management(JSR-77),原本是用于为应用服务器创建监控管理的API,可各大供应商对此API热情并不高涨。

❑ Java EE Application Deployment(JSR-88),JSR 88是当初用于J2EE应用程序在应用服务器上进行配置和部署的标准API。可是该API始终没有得到众多供应商的支持。

❑ JAX-RPC,是早期通过RPC调用和SOAP Web Services进行交互的编程模型。由于Web Services成熟后从RPC模型中分离出来,被更加健壮和具备更多特性的JAX-WS API所替代。

❑ EJB 2.x Entity Beans CMP,复杂、笨重、过度复杂的EJB2.* 的Entity Bean模型已经被Java EE 5基于POJO的流行轻量级JPA持久层模型所代替。

8.低延迟数据交换:Java API for WebSocket 1.0

越来越多的Web应用程序依赖于从中央服务器及时获取并更新数据。基于HTTP的WebSockets为解决低延迟和双向通信提供了一种解决方案。在WebSocket API的最基层是一个带注释的Java对象(POJO),代码如下:

        @ServerEndpoint("/test")
                  public class TestEndpoint{
            @OnOpen
                  public void onOpen(…){ }
            @OnClose
                  public void onClose(…){ }
            @OnError
                  public void onError(…){ }
            @OnMessage
            }

public void testMessage(String message,…){ }

通过注释 @ServerEndpoint来指定一个URI,如客户端连接、接收消息和客户端断开这样的回调函数都可以用注释来指定。WebSocket API的最基层支持发送和接收简单文本和二进制信息。API的简单性也使得开发人员可以快速入门。

当然,功能丰富的应用拥有更复杂的需求,因此需要支持对最基础的网络协议进行控制和自定义,而WebSocket API正好能够满足以上需求。另外,WebSocket利用现有Web容器的安全特性,开发人员只需付出较少的代价就可以建立良好的保密通信。

9.简化应用数据分析和处理:Java API for JSON Processing 1.0

JSON作为一个轻量级的数据交换格式,被应用在许多流行的Web服务中用来调用和返回数据。许多流行的在线服务都是使用基于JSON的RESTful服务。在Java EE 7之前,Java应用程序使用了不同的类库去生成和解析RESTful服务中的JSON对象。然而,现在这个功能已被标准化。

通过Java API中的JSON Processing 1.0,JSON处理过程标准化为一个单一的API,应用程序不需要使用第三方的类库。这样使得应用程序更小更简便。同时API包括了支持任何转换器和生成器实现的插件,使得开发人员可以选择最好的实现方式去完成工作。

10.可扩展的RESTful服务:JAX-RS 2.0

JAX-RS 2.0增加了异步响应处理,这对于支持对数据有着高要求的HTML 5客户端的扩展是至关重要的。异步处理是一种更好更有效利用线程处理的技术。在服务器端,处理请求的线程在等待外部任务去完成时应该避免阻塞,从而保证在这一时间段内到达的其他请求能够得到响应。

同样,在客户端,一个发出请求的线程在等待响应的时候也会发生阻塞,这影响了应用程序的性能。新的JAX-RS 2.0异步客户端API使得客户端调用RESTful可以和其他客户端活动并行执行。异步的好处是使得一个客户端可以同时调用多个后台服务,对于一个使用者来说减少了总体的延迟时间。

同时为增强RESTful服务,JAX-RS 2.0开发人员可以使用过滤器和实体拦截器。这样开发人员就可以使用标准的API实现过滤和拦截功能,使开发过程变得更加便捷和高效。

11.增强开发的易用性:JSF 2.2

Java Server Faces(JSF)是一种用于构建Web应用程序的Java新标准框架。其提供了一种以组件为中心来开发Java Web用户界面的方法,从而简化了开发。在这个版本中,JSF增加了对HTML 5的支持。JSF 2.2增加了一个叫pass-through elements的新功能,并为现有的元素增加了一系列的新属性,如输入元素tel、range和date等。不幸的是,现有的JSF组件不能识别这些新的属性,因此JSF应用程序会忽略这些属性不能进行使用,直到创建专有的解决方案。对于pass-through elements,JSF渲染器将会忽略这些元素,只是把它们传给支持HTML 5的浏览器,这使得可以利用现有的JSF组件来利用HTML 5的特性来正常渲染。

JSF引入了一个新的pass-through命名空间http://xmlns.jcp.org/jsf/passthrough映射到“p:”,任何组件的name/value对都可以以“p:”开始,然后传给浏览器。HTML 5"type=color"不需要JSF组件的任何解析就可以传递给浏览器。代码如下:

        <h:inputText Value="#{bean.color}" P:type="color" />

HTML 5的动态性使得服务器端处理信息更新的请求不断增多。在Java EE 6,Servlet异步I/O通过移除“一个请求需要一个线程”的限制,使一个线程可以处理多个并发请求。这可以使HTML 5客户端快速得到响应。但是,如果服务器端读取数据的速度比客户端发送的速度要快,那么可能会由于缓慢的客户端连接而不能提供更多的数据导致线程阻塞,这样就限制了扩展性。在Java EE 7中使用新的事件驱动API Servlet 3.1从客户端读取数据将不会造成阻塞。如果有数据可用时,Servlet线程将会读取和处理这些数据,否则就去处理其他请求。

12.提高批处理应用程序的效率使开发过程变得更加便捷和高效

绝大部分的Java EE应用都是在线用户驱动的系统,但同时有一些需要进行批处理的服务器端应用程序,尤其是离线分析和ETL等。这些面向批处理的应用程序是非交互式的、需要长时间运行,这些任务通常需要大量计算,同时可以按顺序或者并行执行,并可以通过特定的事件启动或者定时调度。批处理较适合选择闲置的时间进行处理,这样可以有效利用计算机资源。

以前,对于批处理程序没有标准的Java编程模型。现在,批处理应用程序为Java平台提供了如图1-2所示的非常容易理解的模型。批处理过程包括任务、步骤、存储库、读取—处理—写入模式和工作流等。

图1-2 用步骤描述工作

如图1-2所示,一个任务job代表一系列执行离散业务流程但又密切相关的步骤。步骤可以按顺序或者并行执行。同时,在同一个工作流中,当前步骤是可选的,基于前一步骤的运行结果决定当前步骤将被执行或者跳过。另外,步骤可以根据实际的需要被重新执行。存储库(repository)存储了当前任务的信息,如任务的最后执行时间。通过操作员(operator)可以对任务进行排序、开始、停止、暂停和取消操作。