关闭。这个问题需要更多focused .它目前不接受答案。
想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .
5年前关闭。
Improve this question
让我们分享基于 Java 的 Web 应用程序架构!
使用 Java 实现的 Web 应用程序有许多不同的体系结构。这个问题的答案可以作为各种 Web 应用程序设计及其优缺点的库。虽然我意识到答案将是主观的,但让我们尽量保持客观并激发我们列出的利弊。
使用您喜欢的详细程度来描述您的架构。为了让您的答案具有任何值(value),您至少必须描述您所描述的架构中使用的主要技术和想法。最后但并非最不重要的一点是,我们什么时候应该使用您的架构?
我会开始...
架构概述
我们使用基于 Sun 开放标准的 3 层架构,如 Java EE、Java Persistence API、Servlet 和 Java Server Pages。
层间可能的通信流表示为:
Persistence <-> Business <-> Presentation
例如,表示层从不调用或执行持久性操作,它总是通过业务层来完成。该架构旨在满足高可用性 Web 应用程序的需求。
坚持
执行创建、读取、更新和删除 ( CRUD ) 持久性操作。在我们的例子中,我们使用 ( Java Persistence API ) JPA 并且我们目前使用 Hibernate作为我们的持久性提供者并使用 its EntityManager .
该层分为多个类,其中每个类处理特定类型的实体(即与购物车相关的实体可能由单个持久性类处理),并且由一个且仅一个管理器使用。
另外这一层还存储了JPA entities诸如
Account
之类的东西, ShoppingCart
等。业务
所有与 Web 应用程序功能相关的逻辑都位于这一层。此功能可以为想要使用她/他的信用卡在线支付产品的客户发起汇款。它也可以是创建新用户、删除用户或计算基于 Web 的游戏中的战斗结果。
该层分为多个类,每个类都用
@Stateless
注释。成为Stateless Session Bean (SLSB)。每个 SLSB 被称为一个管理器,例如一个管理器可以是一个被注释的类,称为 AccountManager
.当
AccountManager
需要执行 CRUD 操作,它会对 AccountManagerPersistence
的实例进行适当的调用。 ,它是持久层中的一个类。 AccountManager
中两种方法的粗略草图可能是:...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
我们使用 container manager transactions所以我们不必做我们自己的事务划分。在幕后发生的事情是,我们在进入 SLSB 方法时启动一个事务,并在退出该方法之前立即提交(或回滚)它。这是一个约定优于配置的例子,但除了默认的Required,我们还不需要任何东西。
以下是 Sun 的 Java EE 5 教程如何解释 Required transaction attribute对于 Enterprise JavaBeans (EJB):
If the client is running within a transaction and invokes the enterprise bean’s method, the method executes within the client’s transaction. If the client is not associated with a transaction, the container starts a new transaction before running the method.
The Required attribute is the implicit transaction attribute for all enterprise bean methods running with container-managed transaction demarcation. You typically do not set the Required attribute unless you need to override another transaction attribute. Because transaction attributes are declarative, you can easily change them later.
介绍
我们的表示层负责……表示!它负责用户界面,并通过构建 HTML 页面和通过 GET 和 POST 请求接收用户输入来向用户显示信息。我们目前使用的是旧版 Servlet 's + Java Server Pages ( JSP ) 组合。
该层调用业务层管理器中的方法来执行用户请求的操作并接收信息显示在网页中。有时从业务层收到的信息是不太复杂的类型,如
String
的和 int
egers,其他时间 JPA entities .架构的优缺点
优点
缺点
@NamedQuery
将经常使用的查询存储为命名查询。 JPA 实体类上的注释。如果您在持久性类中尽可能多地与持久性相关,就像在我们的体系结构中一样,这将分散您可能会发现查询的位置,以包括 JPA 实体。概述持久性操作将更加困难,因此更难维护。 Account
和 ShoppingCart
,它们真的不是业务对象吗?这样做是因为您必须接触这些类并将它们转换为 JPA 知道如何处理的实体。 fetch=FetchType.LAZY
)从表示层内部从数据库加载。它会触发异常。在返回包含这些类型字段的实体之前,我们必须确保调用相关的 getter。另一种选择是使用 Java 持久性查询语言 ( JPQL ) 并执行 FETCH JOIN
.然而,这两个选项都有点麻烦。 最佳答案
好的,我会做一个(较短的):
我们使用 Sping 事务支持,并在进入服务层时启动事务,向下传播到 DAO 调用。 Service 层拥有最多的业务模型知识,而 DAO 则做相对简单的 CRUD 工作。
出于性能原因,一些更复杂的查询内容由后端中更复杂的查询处理。
在我们的案例中使用 Spring 的优点是我们可以拥有依赖于国家/语言的实例,这些实例位于 Spring Proxy 类之后。根据 session 中的用户,拨打电话时使用正确的国家/地区/语言实现。
事务管理几乎是透明的,运行时异常回滚。我们尽可能使用未经检查的异常。我们曾经做过受检异常,但是随着 Spring 的引入,我看到了非受检异常的好处,只有在可能的情况下才处理异常。它避免了很多样板“捕获/重新抛出”或“抛出”的东西。
对不起,它比你的帖子短,希望你觉得这很有趣......
关于java - 描述您用于 Java Web 应用程序的架构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/286846/