# JavaEE
# 基本概念
Java有三个基本版本:
- JavaSE,主要用于开发部署桌面的应用程序。
- JavaEE,针对企业应用的开发,电子商务,ERP等系统。
- JavaME,针对小型电子设备,比如移动电话,汽车导航系统。
它们三者之间的关系如下:
JavaEE,是Java Platform Enterprise Edition,它是Sun公司为企业级应用推出的标准平台,用来开发B/S架构软件。Java EE既可以说是一个框架,也可以说是一种规范。在2018年3月,Oracle决定把JavaEE移交给开源组织Eclipse基金会,但是不希望JavaEE继续使用Java这个名字,后被更名为Jakarta EE。
此处引用自什么是JavaEE (opens new window)。
在企业应用最开始的时候,因为生态不程序,需要有人牵头规范引导Java的发展,Java EE曾经引领了企业级应用的开发。随着Java的成熟,出现了很多Java EE组件的替代者,比如Hibernate、Spring,这时Java官方提出的JavaEE规范并不受欢迎,比如他们制定了JSF规范,但实际企业开发喜欢用Struts 2、Spring MVC;他们制定了EJB规范,但实际企业开发往往还是喜欢用Spring;他们制定了JPA规范,但实际企业开发往往还是喜欢直接用Hibernate、MyBatis,我们平时使用的也只是少量的Java EE规范,比如Servlet、JSP、JMS,没有用Oracle提供的JavaEE版本。
Oracle之所以放弃Java EE,正体现了JavaEE丧失了对企业应用开发的无奈,Oracle每年为制定Java EE规范投入不少人力、财力,但制定的规范最终并没有获得市场的青睐。
# JavaEE核心规范
JavaEE的13个规范其实就是JavaEE的13个API文档,是一种比较抽象的标准。此处参考javaEE体系结构:13种核心技术规范 (opens new window)。
# JavaServerPages
JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理,然后将生成的HTML页面返回给客户端的浏览器。JSP可以使用Servlet提供的API,一般和JavaBean结合使用,从而将界面表现和业务逻辑分离。
# JavaIDL
Java IDL(Interface Description Language)/CORBA(Common Object Broker Architecture),Java接口定义语言/公用对象请求代理程序体系结构。IDL是用来描述软件组件接口的一种计算机语言。IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信交流。
# JNDI
JNDI(Java Naming and Directory Interfaces)Java 的命名和目录接口。JNDI是命名目录服务的抽象接口集合,为企业级应用提供了统一的标准化连接,使Java能够无缝地获取任何可目录化的企业信息。在JavaEE体系中,JNDI用来定位各种对象,包括EJB、数据库驱动、JDBC数据源及消息连接等。由于JNDI是独立于目录协议的,因此还可以用JNDI访问各种特定的目录服务,如LDAP(轻量目录访问协议)、NDS(服务器目录访问服务)。
# EJB
EJB(Enterprise JavaBean),是基于分布式事务处理的企业级应用程序的组件。EJB是用于开发和部署多层结构的、分布式的、面向对象的Java应用系统的跨平台的构件体系结构。
在开发分布式系统时, 采用EJB可以使得开发商业应用系统变得容易, 应用系统可以在一个支持EJB的环境中开发, 开发完之后部署在其它的EJB环境中, 随着需求的改变, 应用系统可以不加修改地迁移到其它功能更强、更复杂的服务器上。EJB在系统实现业务逻辑层里面负责表示程序的逻辑和提供访问数据库的接口。
- EJB组件:JavaBean是在编程环境(IDE)中能够被可视化处理的可重用组件,是实现分布式业务逻辑的 Java 组件。我们在开发的时候可以利用这些组件,像搭积木一样建立面向对象的分布式应用。
- EJB容器:是EJB组件的运行环境,为部署EJB组件提供服务,包括事务、安全、远程客户端的网络发布、资源管理等。
- EJB服务器:管理EJB容器的高端进程或应用程序,并提供对系统服务的访问。
- EJB客户端:调用EJB组件的应该称为EJB客户端,客户端可以运行在Web容器中。
# JDBC
JDBC(Java Database)数据库连接,JDBC是一组用于执行SQL的Java API ,为访问不同的数据库提供了一种统一的途径,几乎所有的关系型数据库厂商(DBMS)都提供了JDBC的服务或驱动。JDBC对数据库的访问也具有平台无关性。
# RMI
RMI(Remote Method Invoke)远程方法调用,RMI协议能够让在某个Java虚拟机上的对象,像调用本地对象一样调用另一个Java虚拟机中的对象上的方法。它使用了序列化方式在客户端和服务器端传送数据。它是一种被EJB使用的更底层的协议。
# Servlet
Servlet是一种小型的Java程序,它扩展了Web服务器的功能。作为一种服务器端的应用,当被请求时开始执行。Servlet提供的功能大多与JSP类似,不过实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码,而servlets全部由Java写成并且生成HTML。
# XML
XML(Extensible Markup Language)可扩展标记语言,XML是一种用于标记电子文件使其具有结构性的标记语言,它被用来在不同的商务过程中共享数据。
# JMS
JMS(Java Message Service)Java消息服务,JMS是Java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。JMS用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域,有支持发布/订阅(publish/subscribe)类型的域,并且提供对下列类型的支持:经认可的消息传递,事务型消息的传递,一致性消息和具有持久性的订阅者支持。它具有如下三个优点:
- 提供消息灵活性
- 松散耦合
- 异步性
# JTA
JTA(Java Transaction API)Java事务API。在JavaEE应用中,事务是一个不可或缺的组件模型,它保证了用户操作ACID(即原子、一致、隔离、持久)属性。对于那些跨数据源(例如多个数据库,或者数据库与JMS)的大型应用,则必须使用全局事务JTA。应用系统可以由JTA定义的标准API访问各种事务监控,JTA为JavaEE平台提供了分布式事务服务,它隔离了事务与底层的资源,实现了透明的事务管理方式。
# JavaMail
JavaMail是用于存取邮件服务器的API,它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器,也支持IMAP服务器和POP服务器。
# JTS
JTS(Java Transaction Service)Java事务服务,JTS是一个组件事务监视器。JTS是CORBA OTS事务监控的基本实现。JTS规定了事务管理器的实现方式。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。
# JAF
JAF(JavaBean Activation Framework),JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成Java对象,或者转换自Java对象。大多数应用都可以不需要直接使用JAF。
# MVC
最常提的MVC是指应用被划分为模型层(Model),视图层(View),控制层(Controller)三部分,模型层负责持久化,视图层负责呈现内容,控制层负责业务逻辑。
JavaEE中的MVC指:
# SSH
SSH是Struts+Spring+Hibernate的组成方式,Struts实现MVC,Spring负责架构的结合,Hibernate进行数据的持久化。它分为:
- entity(实体层):单纯的对数据库字段进行封装
- dao(数据访问层):负责连接数据库,使用hibernate对数据库进行操作
- biz(业务逻辑层):包含业务逻辑,通过调用dao层实现业务数据的持久化
- action(控制层):是Struts带来的层,负责与页面进行数据交互和调用biz层进行业务逻辑处理
也会有人根据实际需要重新划分,参考基于SSH开发架构的重新分层 (opens new window)。
数据流向为底层数据库(具体数据的存储)——>dao(实现从表中读数据)——>domain(表与实体进行关联,进行实体的定义,set,get方法的定义)——>service(逻辑的实现,进行数据关联,方便底层取数据)——>Action,JSP(方便为前段提供数据)。
# SSM
主要分为三层:
- 界面层,比如使用servlet作为该层控制器,jsp作为该层视图。
- 业务逻辑层(service层),组合DAO层中的简单方法,形成复杂功能,进行业务逻辑方面操作。
- dao层,该层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此。
有的可能还有domain层,domain层通常是与数据库表一一对应的javaBean。domain层涉及到领域模型(domain model),是领域内的概念类或现实世界中对象的可视化表示,又称为概念模型或分析对象模型,它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。
领域模型又分为贫血模型和充血模型:
- 贫血模型是指使用的领域对象中只有setter和getter方法(POJO),所有的业务逻辑都不包含在领域对象中而是放在业务逻辑层。有人将我们这里说的贫血模型进一步划分成失血模型(领域对象完全没有业务逻辑)和贫血模型(领域对象有少量的业务逻辑),我们这里就不对此加以区分了。
- 充血模型将大多数业务逻辑和持久化放在领域对象中,业务逻辑(业务门面)只是完成对业务逻辑的封装、事务和权限等的处理。
下面两张图分别展示了贫血模型和充血模型的分层架构:
# 其他概念
# POJO
POJO全称是Plain Ordinary Java Object / Pure Old Java Object,具有一部分getter/setter方法的那种类就可以称作POJO,后来"POJO"主要用来指代那些没用遵从特定的Java对象模型,约定或框架如EJB的Java对象。
# JavaBean
JavaBean同POJO差不多,但是JavaBean概念上被看成一种可重用组件技术,它的方法命名,构造及行为必须符合特定的约定:
- 这个类必须有一个公共的缺省构造函数。
- 这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。
- 这个类应是可序列化的。
因为这些要求主要是靠约定而不是靠实现接口,所以许多开发者把JavaBean看作遵从特定命名约定的POJO。简而言之,当一个Pojo可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,他就是一个JavaBean。
# EnterpriseJavaBean
Enterprise JavaBean(EJB),是J2EE的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。它分为:
1.Session Bean用于实现业务逻辑,它可以是有状态的,也可以是无状态的。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库,但更多时候,它会通过Entity Bean实现数据访问。 这个类一般用单例模式来实现,因为每次连接都需要用到它。
2.Entity Bean是域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象,事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个 Entity Bean会同时从数据库中删除对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。Java Persistence 1.0规范中的entity bean仅作为普通Java对象(POJO)来使用,并且是映射到关系数据库表的。与其他类型的EJB不同,entity bean可以被分配,序列化,并像任何其他POJO那样通过网络被发送出去。
3.MessageDriven Bean是EJB2.0中引入的新的企业Bean,它基于JMS消息,只能接收客户端发送的JMS消息然后处理。MDB实际上是一个异步的无状态Session Bean,客户端调用MDB后无需等待,立刻返回,MDB将异步处理客户请求。这适合于需要异步处理请求的场合,比如订单处理,这样就能避免客户端长时间的等待一个方法调用直到返回结果。
# EJB和JavaBean区别
JavaBean 和 EJB 有一些基本相同之处。它们都是用一组特性创建,以执行其特定任务的对象或组件。但JavaBean 是使用 java.beans包开发的,主要是一台机器上同一个地址空间中运行的组件,是进程内组件。Enterprise Bean 是使用 javax.ejb 包开发的,是 Java Enterprise Edition 的一部分。Enterprise Bean 是在多台机器上跨几个地址空间运行的组件,因此 Enterprise Bean 是进程间组件。JavaBean 通常用作 GUI 窗口小部件,而 Enterprise Bean 则用作分布式商业对象。