需要帮助定义/理解 Java EE“堆栈”
Posted
技术标签:
【中文标题】需要帮助定义/理解 Java EE“堆栈”【英文标题】:Need Help Defining/Understanding the Java EE "Stack" 【发布时间】:2011-09-19 23:01:34 【问题描述】:LAMP 是从左到右(从下到上)定义为 Linux/Apache/mysql/php 的堆栈,或者通常您可以将其视为操作系统/Web 服务器/数据库/脚本语言。在通用形式中,您可以弹出任何操作系统,例如 Windows 而不是 Linux,以获取 WAMP 或放入其他数据库,甚至可以运行 PHP 以外的其他语言,例如 Ruby。但是,通常每件事你都只有一个。一个数据库、一个操作系统、一个 Web 服务器,尽管您的应用程序可能会从一个堆栈转换到另一个堆栈,并进行一些有限的更改。
我已经在 LAMP 堆栈中进行了几年的开发,并且一直在阅读有关 JSF 以及组件库 RichFaces 和 IceFaces 的文章。使用支持 AJAX 的组件构建网站 UI 并获得各种漂亮的东西(如验证)以及免费的凌乱 AJAX 调用的整个想法确实令人兴奋。
问题是我很难理解什么通用组件构成了 Java EE 堆栈。根据我的研究,您似乎可以从以下类别中构建“Java EE 堆栈”:
Java EE 应用服务器 - JBoss、Tomcat
数据库 - MySQL、Oracle
数据库抽象 - Hibernate,JPA
支持 JSF Ajax 的组件库 - ICEFaces、RICHFaces
我觉得我肯定错过了一些东西。我不确定 Seam 或 Spring 在哪里适合。另外,Hibernate 是使用 JPA 的东西吗?还是 JPA 是一个功能齐全的 API,我可以轻松地单独使用它?容器在哪里适合?我可以出去获取一个容器以在我的 Java EE 应用程序服务器上运行吗?此外,Maven 在哪里适合所有这些?据我所知,它似乎不是 Web 服务堆栈的一部分,而是部署前使用的工具。
我一直在阅读 Rainer Eschen 的 ICEfaces 1.8,他将这个图表描述为一种 Java EE 堆栈。我的猜测是 AppFuse 之于 Java EE 就像 XAMPP 之于 LAMP。真的吗?如果有人可以分解下图中的各个部分以及它们如何组合在一起,那将非常有帮助。
我知道这些问题多种多样。如果我没有提出您认为我应该知道的问题,请随时将其扔掉,或者如果我陈述不正确,请纠正我! Java EE 堆栈,以及与之配套的所有部分,至少可以说是令人生畏的。在我深入研究并开始构建任何东西之前,我只是想很好地掌握高层视图。
谢谢!
【问题讨论】:
为漫长的学习之路做好准备。这些层中的每一层都应该简化它下面的层,但是任何时候你需要做任何不平凡的事情,你可能不得不深入到较低的抽象级别。抽象中总是存在泄漏。我并不是说它们总是很糟糕,但有时我只是想扔掉整个堆栈并做 C/CGI/平面文件。 PHP 可以开始看起来不错了.... 这更像是一个讨论而不是一个编程问题(关于代码)。投票将其移至programmers,更合适。 【参考方案1】:该图不是Java EE stack。
这可能有帮助(或没有帮助:):
Java EE 是一个托管运行时系统。 (LAMP 没有这样的顾虑。)
Java EE 使用组件容器通用架构(LAMP 未定义显式组件容器 API)
JBoss、Glassfish 等应用服务器提供 Java EE 容器。 (Tomcat 不支持完整的 Java EE 堆栈。Tomcat 和 Jetty 仅提供 Web 容器(或符合最新规范的 Web 配置文件。)
请注意,Java EE Web 容器 (Servlet) 比完整的 Java EE 堆栈简单得多,但基于相同的架构方法。
Java EE 的 Web 组件(基本上)是 Servlet 和过滤器。各种高阶框架(例如 Faces)建立在此架构之上。 Java EE Web 容器既相对简单又非常有效。它是最接近 LAMP 的东西。
Java EE 的企业组件(由 GlassFish 等 Java EE 应用服务器支持)是各种无状态、有状态和持久性组件(在 Java 领域称为“Bean”)。
Hibernate 是一个 ORM,在完整的 Java EE(例如 EntityBeans)的上下文中是多余的。通常,JPA 与 Web 容器“Java EE”系统一起使用,以连接到后端 JDBC 兼容 RDMBS。甲骨文、MySQL 等等。
您(和/或某些第 3 方库)提供组件。
托管运行时主要关注处理“正交”“企业”“问题”,例如事务完整性,而您,组件/应用程序编写者,应该专注于“业务逻辑” .
Java EE 管理您的引用、事务边界、连接和生命周期组件。
引用:使用语义引用在运行时通过命名空间机制(即 JNDI 和 RMI)查找;以及通过声明性部署描述符进行依赖注入。
生命周期:您的组件将具有正确的启动、工作和关闭阶段。您可以参与这些 LC 活动并在必要时参与(通常没有必要)。这种形式化的 LC 允许架构的分布和扩展。
连接性:广泛解决传入(客户端)和内部 (EIS) 集成点。对于客户端,您拥有 web/RMI/JMS 等。这为您提供了同步 req/rep 语义和异步触发和忘记。对于后端(通常),JCA 指定到其他系统的连接器。 JPA 是 JCA 的一种专门化(理论上不是实践),它专门使用 JDBC 用户 API 处理数据库 EIS。
事务:声明性意味着将事务语义应用于组件的特定方法。这可以在设计时(通过注释)或部署时(通过 XML)完成。
部署包
Java EE 系统通常打包为 WAR(仅适用于 Web)或 EAR(适用于完整堆栈)。
部署描述符
Java EE 的最新规范支持具有合理默认值(或简单映射)的零配置操作。但重要的是,您必须了解这一切是什么,并且在某些时候,任何严肃的 Java EE 应用程序都需要在某种程度上处理这些工件。 (对于 web.xml 来说要容易得多,所以不要惊慌。)它是架构的一个关键方面。明白这一点,其他一切都非常清楚。
Java EE 使用 indirection 来实现它的魔力。这是这里要解决的问题:
我们有一些第 3 方(前一段时间)编写的组件,我们需要在我们的应用程序中使用它们。部署描述符允许映射您的应用程序特定语义,例如组件的名称或其事务语义到组件的通用语义。例如,您可能希望将“Acme-Logger”公开为“My-Very-Own-Logger”。您可以通过将所需的环境名称映射到组件的类来完成此操作。 (原始组件可能有一个注释,将其通用名称简单地声明为“the-logger”)。
实际上,Spring 的出现是因为创建和维护这些映射描述符的痛苦。同样,Spring 是基于容器的系统的另一种方法。
容器
理论上您应该能够将整个容器插入兼容的服务器,但总体思路是您正在为 universal 容器编写 组件。 Java EE 容器。无论如何,正如您可以想象的那样,Java EE 应用服务器供应商并不太热衷于为堆栈提供可插拔的容器 API,因为这会使他们的产品成为完整的商品。
春天
Spring 实际上是 Java EE 的反论点。它是(或曾经是)用于解决 J2EE 痛点的轻量级容器系统(考虑到复杂的架构和部署仪式,如果没有有效的工具,这是完全不合理的)。实际上,Servlet 前端和 Spring 容器是完整的 Java EE 堆栈的替代。也就是说,它们可以共存。
Maven
Maven 是一个构建工具。还有蚂蚁。或者你可以跳上 Gradle。 Maven archetypes 的存在使您可以毫不费力地开始一个基本的 Java EE 项目。
建议:
从(并坚持使用)Web 容器子集开始。 Jetty 或 Tomcat 是容器/服务器的不错选择。
了解 WEB-INF/ 和 web.xml。编写一个简单的 HTTPServlet 扩展,并使用 web.xml 的功能。尝试设置一个过滤器,或者将一些参数绑定到 web-app 上下文中。掌握这些基础知识。其他一切都建立在这些之上。一切。
在 servlet 中,探索提供的 API。了解应用程序、会话和请求“上下文”之间的区别。网络层的一个关键问题。了解如何重定向请求。获取 http 标头等。其他一切都建立在这些之上。掌握这些基础知识。
假设此时您的 HelloWorld 网络应用程序已启动。下一步,尝试 JPA 并将持久性添加到您的项目中。在这里您可以尝试 Spring/Hibernate/Tomcat 教程示例。 Spring 将为您的业务组件(类)设置非 Java EE 容器。 Hibernate 将负责持久化您的数据。执行此操作时会引入几个新工件。 Spring 相关的 xml 文件和 JPA/Hibernate 映射。了解这些及其全部内容。
你快完成了。最后,让我们转向视图或表示问题。这就是 Java (imo) 糟糕的地方,因为它太冗长了,而且这一层完全是关于在此处放置小部件、在此处放置小部件等的无意识重复。
在最简单的情况下(并且开箱即用),您拥有基本的 HTTPServlet 并能够发送回您喜欢的任何内容。您可以在代码中编写 html(一个非常糟糕的主意),或者使用模板方法(Velocity、FreeMarker),或者升级到用于演示的专用组件:JSP、Faces 等。实际上有几十个框架(和方法)用于表示层。
希望这会有所帮助。
【讨论】:
非常感谢您提供的所有见解。你真的花时间回答了我提出的所有问题! 我还有一个简短的问题。通过使用 Web 容器而不是使用成熟的应用程序服务器,您有什么收获或损失? 您丢失了堆栈的一个子集,即 EJB。 JEE 的 Web 容器也(有效地)只为您提供基于 HTTP 的连接器(即没有 RMI 或 JMS)。通常,这对于那里的大量应用程序来说很好。您正在构建网络应用程序吗?除非您指定了 JEE 要求,否则请使用 JEE-Web。【参考方案2】:是的,您发布的图表令人生畏,但您不必使用所有这些东西。这不是所有的必要。
如果您是新手,请保持简单并不断积累。
以下是最基本的必备物品:
-
Servlet 和 JSP。这意味着在 Tomcat 或 Jetty 等 servlet/JSP 引擎上进行部署。 Servlet 是 HTTP 侦听器,用于处理传入请求、与后端类协作以实现它们,并将响应路由到适当的下一个视图。
JSP 是一种用于生成 HTML 的模板解决方案。您应该只使用 JSP 标准标记库 JSTL 编写这些。没有脚本。
用于 UI 的 HTML、CSS 和 javascript。您需要这些用于基于 Web 的 UI。
用于关系数据库访问的 JDBC。
就是这样。有了这些,你就可以走很长的路。
我喜欢春天,但第一次吞下很多东西。做一个或两个没有它的网站。您会更好地理解事物,并更加欣赏 Spring 为您所做的一切。
您不需要 JSF。我认为这是一项正在下降的技术。我亲眼所见的一个 JSF/Faces 应用程序绝对糟糕透了。您可以使用日晷计时页面加载。尽管它被吹捧为 Java EE 标准,但我并不认为它是大赢家。你打算在移动 UI 上运行 JSF 吗?我不这么认为。
UI 是使用 HTML、CSS 和 JavaScript 编写的,与后端的服务通信。这些服务可以是 REST-ful servlet。
Hibernate 是一种对象关系映射技术。如果您没有对象模型,则不需要 Hibernate。如果对象和表之间存在简单的一对一关系,则不需要 Hibernate。如果您喜欢将存储过程作为关系数据库的接口,则不需要 Hibernate。如果您不介意编写一点 SQL 并映射结果,则不需要 Hibernate。 JPA 同上 - Hibernate 是实现 JPA 的一种方式,它从 Hibernate 中得到了很多。
从这些开始并建立起来。如果你试图一次学习所有你引用的东西,你将永远不会有任何收获。
【讨论】:
投票 +1。好答案。在 JEE 世界中,KISS 绝对是值得信赖的东西。我在 JEE 中做了很多工作,如果有什么我会建议它在添加技术和 API 时非常小心。 JEE 的弱点之一(恕我直言)是 1001 个 API,它们都试图告诉您它们将使 JEE 变得多么容易。它们中的大多数都不是那么好或范围非常有限,而且我已经看到很多痛苦是因为承诺免费给你很多东西。 Spring 和 Hibernate 是两个坚实的基础,几乎涵盖了所有内容。从他们开始。 春天是坚实的基础;我不同意 Hibernate。 我还有一个简短的问题。通过使用 Web 容器而不是使用成熟的应用程序服务器,您有什么收获或损失? 更容易部署 - 部署 WAR 包所需的设置更少。以上是关于需要帮助定义/理解 Java EE“堆栈”的主要内容,如果未能解决你的问题,请参考以下文章