前言

最近的这段时间一直在学习Java EE,刚刚完成了从0到1的蜕变,所以顺便整理一下我所了解到的Java EE,给刚入门学习的新人一些头绪,而所谓“启示录”,就是这个意思。

一.Java EE是什么?

Java EE(Java Enterprise Edition)是一种企业级应用的软件架构,同时是一种思想,一套规范。

二.Java EE的发展史

Java Enterprise Edition的发展不知不觉已经12年了,不知道大家有没留意,一开始,Java Enterprise Edition简称“J2EE”,直到版本5才改名为Java EE,而现在最新的版本则是Java EE 6。

到这里,或许有人会问,为什么会有这么多套Java EE规范?这些版本的差别是什么?

1.J2EE1.2的出现,主要是将之前各个单独的规范绑定到一起。

2.J2EE1.3,则是继续完善J2EE体系结构。

3.J2EE1.4,主要是加入了一个重要主题:Web Service

4.而Java EE 5,主题则是“简化”,简化之前复杂的J2EE思想,改善开发体验。

三.Java EE到底要解决什么问题?

1.Java EE解决什么问题?

从Java EE发展背景看,它与“分布式应用”以及“互联网应用”的关系密不可分,而这两者也正是Java EE要解决的问题!

其实,分布式应用随着90年代互联网的兴起逐渐开始普及。在90年代中,各种分布式应用标准逐渐诞生,如:OMG的CORBA,MS的DCOM等,而Sun在推出Java的RMI(Remote Method Invocation)后,便以RMI作为通信基础构建了Java EE。我认为,Java EE最核心要解决的问题就是“分布式应用”。而在接下来的竞争中,Java EE也不负所托,逐渐取代了CORBA,DCOM的地位。

2.分布式应用与RPC

RPC(Remote Procedure Call),在聊到分布式应用时很多人会第一时间想到它。所谓RPC,就是远程调用一个服务,但效果和本地调用一样。在最初的时候,RPC很类似C语言的函数调用,但随着编程语言和技术的发展,特别是面向对象和面向组件技术的广泛应用,便出现了“远程对象/方法调用”。所谓“远程对象/方法调用”其实就是把调用远程对象和本地对象的区别隐藏起来,让调用者可以像使用本地对象那样调用远程对象。从本质上说,最初的RPC和后来的“远程对象/方法调用”稍有不同,在“远程对象/方法调用”中,被调的服务还需要考虑如:对象生命周期管理,事务处理……这些问题。但笼统地说,最初的RPC和“远程对象/方法调用”都称为:RPC,所以之前提到的如:DCOM,CORBA,JAVA的RMI,.NET的Remoting都称为RPC。而我认为,RPC的本质就是:应用协议 + 传输协议。而各种不同的RPC实现之间的区别亦在此。

而所谓的“分布式应用”,实际上可以说是用RPC方式,把各个分布在不同机器的应用模块联合成一个系统。可以说RPC是“分布式应用”的基础,所以就有“以RMI作为通信基础构建了Java EE”这一说了:>

四.Java EE体系结构

这里,我打算从分析“企业级应用”入手,并藉此逐步建立整个Java EE体系。

1.概述Java EE体系结构

为了有印象,我们先来个最简单Java EE架构图看看:

从上图看到,Java EE一般分为4层:

(1)客户端

(2)web层

(3)业务逻辑层

(4)企业信息层(EIS:Enterprise Information System)

呵呵,不要以为Java EE只是描述服务端规范,实际上,它还是包含了一些客户端相关东东,比如:Applet...不过,Java EE的重点还是在服务端这方面,而本文重点也是介绍Java EE在服务端这方面的内容。

2.“企业级应用”分析

(1)分布式应用

首先从总的来看,一个“企业级应用”代表着,这个系统肯定是“非常大型的”,这么大型的系统,这么多的应用,是不可能把应用都部署在一台机器上的,所以“分布式应用”这个需求便顺理成章地出现。理想的“企业级应用”中,各种功能模块应该分布在不同的机器上,在需要某功能的时候,我们可以动态地进行调用。

(2)系统分层

企业应用中,业务的功能会非常复杂。此时,模块间的解耦以及系统的分层开始显得重要,解耦与分层会使得系统结构清晰,并且健壮。而传统的分层模式是一般是:接入层,逻辑层,数据层。

(3)异步

设计分布式应用时,你遇到的第一个问题就是:等待…..在企业级应用中,业务的处理时复杂的。如果把子模块部署到不同机器后,要处理一个业务,很可能需要到多台机器上进行调用;另外,子模块的运算也需要一定的时间,此时,“等待”就出现了。由于你无法预计这个复杂的业务什么时候才能处理完,所以,“异步”这个概念也顺理成章地被引入。(其实,这也体现了软件设计中“快慢分离”的原则)

(4)事务,安全

关于事务的重要性这里就不多说了。

而安全,一般指对某个模块的授权,身份验证等等,在企业级应用中,安全绝对是重要的一块。

(5)Java EE平台与其他已有资源、服务、系统的整合

在Java EE出来之前,很多公司很可能已经建立了比较完善的企业信息系统(EIS),显然,和这些已有的系统整合,在企业级应用中显得尤为重要。

3.Java EE体系结构详述

OK,现在让我们来逐步了解,Java EE每个部件的作用吧。

(1)Servlet,JSP

JSP,Servlet同属“web层”,并都属于“动态网页技术”。所谓“动态网页技术”和传统的“静态网页技术”不一样,传统的“静态网页技术”说白就是把做好的html文件直接上传到服务器并直接供客户浏览,而“动态网页技术”则是每次都根据用户请求,动态生成响应页面并返回。“动态网页技术”的好处不言自明,无论从灵活性,数据保密性…等方面说都是“静态网页”所无法媲美的。但“动态网页技术”也是有缺点的,就是相对较慢,现在的解决方案一般是:把“动态网页”中相对固定的部分做缓存,即所谓“静态页面”。(额.…..“静态网页”和“静态页面”本质上没什么区别,都是静态页面,但思想上却有很大区别。而现在的程序员一般会对“静态”这个词赋予一个新的含义:“缓存”)

【1】Servlet

Servlet实际上就是按照Servlet规范编写的一个java类,与传统的命令行启动的Java应用程序不同,Servlet位于Web服务器内部,并由Web服务器加载并调用。

【2】JSP

JSP全称是:JavaServer Page。这项技术的推出目的其实很简单,为了弥补Servlet一个很重要的缺陷:“麻烦”。

先看看Servlet到底什么地方让人觉得麻烦,下面是一个Servlet处理Get请求例子:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("处理GET请求ing......");
response.setContentType("text/html;charset=GB2312");
PrintWriter out = response.getWriter();
out.println("<HTML>"); // 静态内容
out.println("<BODY>"); // 静态内容
out.println("Hyddd's Servlet Demo " + new Date().toString()); // 动态内容
out.println("</BODY>"); // 静态内容
out.println("</HTML>"); // 静态内容
}

从上面这个例子,相信大家已经发现问题了,Servlet主要是把动态内容混合到静态内容中以产生html,这导致Servlet代码中将会输出大量的html标识,哇,地狱,简直就是地狱,同时,这也非常不利于程序员和UI美工的配合(不要指望美工人员会和你一起写html标识)。为了解决这些问题,JSP诞生了。

JSP是一种建立在Servlet规范之上的动态网页技术,通常做法是:在html页面中嵌入JSP标记和脚本代码。JSP把静态内容和动态内容的分离,实现了内容和表示的分离。

【3】Servlet与JSP的关系

上图描述得比较清楚了,JSP文件先是转换为Servlet类,然后编译,并启动Servlet实例响应客户端请求。为什么说JSP是建立在Servlet上的动态网页技术,从这里可以看出来。

Web层主要就是JSP以及Sevlet这两项技术。

(2)EJB(Enterprise JavaBean)

之前说过,分布式应用是Java EE一个基础的需求,额……那在不同机器上的“分布式”的应用到底会以一个什么样的形态出现呢?答案就是:EJB。EJB属于业务逻辑层上的东东。

所谓Bean,其实是“组件”的意思。EJB可以让你像搭积木一样,通过本地/分布式调用组装不同应用到大型应用中,使你能集中精力来处理企业的业务逻辑,而像事务、网络、安全等等这些底层服务则统统留给EJB服务器开发商来解决。

利用基于组件的开发,可以把代码重用上升到一个新的高度。利用面向对象开发,重用的是类,而基于组件时,重用的则是更大的功能块。

【1】EJB vs Java Bean

我个人认为,Java Bean相当于是数据存储类(不涉及具体业务逻辑),专门用来存数数据,提供getter,setter方法,并且在JVM上可直接运行。EJB则相当于一个功能模块,提供业务逻辑的服务,而运行时,则需要EJB容器的帮助。

EJB是业务逻辑层最重要的技术哦!

(3)Container(容器)

Container这个概念经常在Java EE中出现,所谓Container,在Java EE 5 Tutorial中有这样一段解释:“Containers are the interface between a component and the low-level platform-specific functionality that supports the component.”,而Container的作用,我个人的认为是:为“应用程序”提供一个环境,使其可以不必须关注某些问题,如:系统环境变量,事务,生命周期…….通俗地说,Container就像“秘书”,帮“应用程序”管理着各种杂乱的问题,为其提供运行时支持

其中,Java EE里有两个很重要的容器:Web容器EJB容器

【1】Web容器

Web容器是用于托管“Web应用程序”的J2EE容器,主要负责管理“Servlet”和“JSP”运行。

【2】Servlet容器

其实,上图中的Servlet指的就是Servlet容器。而Servlet的设计初衷,实际是基于线程池的更好的线程容器,见下图:

【3】EJB容器

EJB容器主要负责管理“EJB”的运行。

而EJB的设计实际上是基于对象池的思想,你可以认为EJB=对象池+远程对象池。见下图:

【4】Servlet与EJB

其实,根据Servlet和EJB的设计初衷,我们已经可以看出Java EE对两者角色的定义了。线程的本质决定了Servlet只适合一些比较简单的轻量级应用;一旦问题复杂了,最好的就是使用EJB。

(4)RMI

RMI全称:Java Remote Method Invocation,就是利用Java对象序列化的机制,实现远程类对象的实例化以及调用的方法。

RMI在Java EE中的主要是负责解决通信问题,特别是不同的EJB容器之间的通信。大家知道,在分布式应用中,各个功能模块(EJB)之间通信需要有统一的RPC协议,否则没法通信,而RMI就是负责这方面的工作。

【1】RMI 与 CORB

可以说,RMI就是CORBA的Java版实现。

【2】再谈“远程调用”

现在主流的远程调用方式,不管是com/com+,soap,webservice,rmi,.net remoting,说白了都一样的,就是序列化,网络传输,反序列化

序列化方式:同种runtime的,可以native的二进制序列化,序列化的效率高。文本的序列化(xml/json/自定义格式)的方式,可以跨平台和语言,一般基于中间类型。但此序列化方式的效率低,数据量也偏大。

网络传输:则可以使socket/http或是自定义协议的。 socket数据冗余最小,效率最高。RMI其实是socket上的自定义协议。 http要走http的报文,文本的方式最合适,实现最简单,开发和部署方便。

(5)JMS

JMS:Java Message Service。JMS提供一种消息机制,主要作用是提供异步通信的支持,是Java EE的重要基础模块。值得注意,异步通信,一般都采用消息机制,这种情况在Windows中最常见。

(6)JTA

JTA:Java Transaction API,主要提供事务服务和分布式事务管理功能,保证分布式事务的一致性,是Java EE的重要的基础模块。

(7)JAAS

JAAS:Java Authentication Authorization Service(Java认证于授权服务),提供了对Java组件的安全保护,如哪些Servelt,JSP能被哪些用户访问,哪些EJB能被调用等。但需要注意的是,JAAS只提供了对JAVAEE组件的保护,对于企业应用业务的权限,它是做不到的。

(8)Connector

Connector主要作用就是把其他已有的资源、服务、系统整合到Java EE系统中。不同的服务提供商和Java EE平台会定义不同的协议,而Connector就是指这些协议的实现。

至此为止,Java EE的核心模块介绍完毕,让我们来看看J2EE 1.3的架构图(当时的J2EE架构还是比较简单的):

4.J2EE 1.4 以及 Java EE 5体系结构

(1)J2EE 1.4 体系结构

J2EE 1.4加入了一个重要的主题:“Web Service”,包括:JAX-RPC,SAAJ,Web Srvcs,JAXR都属于这一块的东西。

(2)Java EE 5体系结构

关于Java EE 5这里就不详细介绍了:>,大家有兴趣可以参考《Java EE Tutorial 5》。

后记

这篇文章写了我3天,同时也翻了N多资料,希望本文确实对各位初学者有所帮助,同时本文包含很多个人观点,如有错误敬请指出:>

关于Java EE 5,如果后续有时间我会继续整理。

重要参考资料

【1】《JAVA EE 5 的发展史

【2】《Java程序员 上班那点儿事

【3】《Java EE Tutorial 5

【4】《J2EE到底是什么?

Java EE启示录的更多相关文章

  1. Java EE发展史

    前言 最近的这段时间一直在学习Java EE,刚刚完成了从0到1的蜕变,所以顺便整理一下我所了解到的Java EE,给刚入门学习的新人一些头绪,而所谓“启示录”,就是这个意思. 一.Java EE是什 ...

  2. Eclipse for Java EE软件操作集锦(一)

    以下是我在Java网站开发过程中,关于软件操作Eclipse中,遇到的一些问题并提供了解决方案.一.java web开发使用的集成开发工具是eclipse for Java EE 官方下载地址:htt ...

  3. 【Java EE 学习 80 上】【WebService】

    一.WebService概述 什么是WebService,顾名思义,就是基于Web的服务,它使用Http方式接收和响应外部系统的某种请求,从而实现远程调用.WebService实际上就是依据某些标准, ...

  4. 【Java EE 学习 74 上】【数据采集系统第六天】【使用Jfreechart的统计图实现】【Jfreechart的基本使用方法】

    之前已经实现了数据的采集,现在已经有了基本的数据,下一步就需要使用这些数据实现统计图的绘制了.这里使用Jfreechart实现这些统计图的绘制.首先看一下Jfreechart的基本用法,只有知道了它的 ...

  5. 【Java EE 学习 69 中】【数据采集系统第一天】【SSH框架搭建】

    经过23天的艰苦斗争,终于搞定了数据采集系统~徐培成老师很厉害啊,明明只是用了10天就搞定的项目我却做了23天,还是模仿的...呵呵,算了,总之最后总算是完成了,现在该好好整理该项目了. 第一天的内容 ...

  6. 【Java EE 学习 67 下】【OA项目练习】【SSH整合JBPM工作流】【JBPM项目实战】

    一.SSH整合JBPM JBPM基础见http://www.cnblogs.com/kuangdaoyizhimei/p/4981551.html 现在将要实现SSH和JBPM的整合. 1.添加jar ...

  7. 轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)

    轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)(国家级奖项获奖作品升级版,四版累计印刷27次发行量超10万册的轻量级Jav ...

  8. MyEclipse的项目中把 java EE 5 Libraries 删掉后怎么重新导入

    myeclipse中鼠标右击项目->properties->java Build Path=>Libraries=>Add Library...=>选择MyEclipse ...

  9. 《Java EE 开发技术与案例教程》 这是一本好书啊:简洁精辟(相见恨晚)

    第一章:Java EE 概述 1.get:JPA:Java Persistence API, 数据持久化API: JPA是一种ORM规范,它的实现实例:Hibernate.mybatis 2.Web ...

随机推荐

  1. input输入框输入小写字母自动转换成大写字母

    input输入框输入小写字母自动转换成大写字母有两种方法 1.用js onkeyup事件,即时把字母转换为大写字母: html里input加上 <input type="text&qu ...

  2. 巨蟒python全栈开发数据库前端3:CSS基础2

    1.文本属性 2.背景属性 3.边框属性 4.display属性 5.盒子模型

  3. ArcGIS runtime sdk for wpf 授权

    这两天由于runtime sdk for wpf的授权和runtime sdk 其他产品的授权的不一样导致自己混乱不堪. 总结下吧. sdk 简介 当前ArcGIS runtime sdk 包括一系列 ...

  4. A4纸网页打印中对应像素的设定和换算

    最近开发项目时遇到了网页打印的问题,这是问题之二,打印宽度设置 在公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot PerInch)指标.  经过我仔细的测试,发现了网页打印中,默认采用 ...

  5. .net DataSet 导出到Excel

    public void CreateExcel(DataSet ds, string typeid, stringFileName)        {           HttpResponse r ...

  6. 关于Nginx部署Django项目的资料收集

    参考:https://www.cnblogs.com/chenice/p/6921727.html 参考:https://blog.csdn.net/fengzq15/article/details/ ...

  7. BeanUtils.copyProperties()

    BeanUtils.copyProperties() PropertyUtils.copyProperties() 通过反射将一个对象的值赋值个另外一个对象(前提是对象中属性的名字相同). 后付前 P ...

  8. Java并发—并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

  9. Elasticsearch中文搜索环境搭建

    Elasticsearch是一个建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎,功能强大,最近刚好要研究搜索这一块,简要记录备日后查阅 安装Java JDK,由于Lucene是用J ...

  10. go——反射

    反射(reflect)让我们能在运行期探知对象地类型信息和内存结构,这从一定程度上弥补了静态语言在动态行为上地不足.和C数据结构一样,Go对象头部并没有类型指针,通过其自身是无法在运行期获知任何类型相 ...