让我们分享基于Java的Web应用程序体系结构!
Web应用程序有许多不同的体系结构,这些体系结构将使用Java来实现。这个问题的答案可以用作各种Web应用程序设计的库,各有其优缺点。虽然我意识到答案将是主观的,但让我们尽可能做到客观,并激发我们列出的利弊。
使用您喜欢的详细程度描述体系结构。为了使您的答案具有任何价值,您至少必须描述所描述的体系结构中使用的主要技术和思想。最后但并非最不重要的一点是,我们什么
时候 应该使用您的体系结构?
我开始…
我们使用基于Sun的开放标准(如Java EE,Java Persistence API,Servlet和Java Server
Pages)的三层体系结构。
层之间可能的通信流由以下方式表示:
Persistence <-> Business <-> Presentation
例如,这意味着表示层从不调用或执行持久性操作,而是始终通过业务层进行操作。该体系结构旨在满足高可用性Web应用程序的需求。
执行创建,读取,更新和删除(CRUD)持久性操作。在本例中,我们正在使用(Java
Persistence
API)JPA,并且当前使用Hibernate作为持久性提供程序,并使用其EntityManager。
该层分为多个类别,其中有某种类型的实体的每一类交易(涉及到购物车即实体可能是由一个单独的持久类得到处理),并 使用 一个且只有一个 经理 。
此外,该层还存储JPA实体哪些是喜欢的东西Account
,ShoppingCart
等等。
与Web应用程序功能相关的所有逻辑均位于此层。此功能可能是为想要使用她/他的信用卡在线购买产品的客户发起汇款。也可能是在基于网络的游戏中创建新用户,删除用户或计算战斗结果。
该层分为多个类,每个类都带有注释,@Stateless
以成为无状态会话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
}
我们使用容器管理器事务,因此我们不必自己进行事务划分。根本上发生的事情是,我们在进入SLSB方法时启动一个事务,并在退出该方法之前立即提交(或回滚)它。这是约定而不是配置的示例,但是除了默认值(必需)外,我们不需要任何其他东西。
这是Sun的Java EE 5教程解释Enterprise
JavaBeans(EJB)的Required事务属性的方式:
如果客户端在事务中运行并调用企业bean的方法,则该方法在客户端的事务中执行。如果客户端未与事务关联,则容器在运行该方法之前启动一个新事务。
Required属性是使用容器管理的事务划分运行的所有企业Bean方法的隐式事务属性。除非您需要覆盖另一个事务属性,否则通常不设置Required属性。因为事务属性是声明性的,所以以后可以轻松更改它们。
我们的演示层负责…演示!它负责用户界面,并通过构建HTML页面并通过GET和POST请求接收用户输入来向用户显示信息。我们目前正在使用旧的Servlet
+ Java Server Pages(JSP)组合。
该层调用业务层 管理器
中的方法以执行用户请求的操作并接收要在网页中显示的信息。有时,从业务层接收到的信息是不太复杂的类型,String
年代和int
egers,并在其他时间JPA实体。
@NamedQuery
JPA实体类上的注释将常用查询存储为命名查询。如果与我们的体系结构中的持久性类中的持久性有尽可能多的关联,这将扩展您可以在其中找到包括JPA实体的查询的位置。概述持久性操作将因此变得更加困难,因此难以维护。Account
和ShoppingCart
,它们不是真正的业务对象吗?通过这种方式可以完成此操作,因为您必须触摸这些类并将它们变成JPA知道如何处理的实体。fetch=FetchType.LAZY
从表示层内部(使用)从数据库加载。它将触发异常。在返回包含这些字段的实体之前,我们必须确保调用相关的获取器。另一种选择是使用Java持久性查询语言(JPQL)并执行FETCH JOIN
。但是,这两个选项都比较麻烦。好吧,我将做一个(简短的):
我们使用Sping事务支持,并在进入服务层后开始事务,扩展到DAO调用。服务层具有最强的业务模型知识,而DAO则进行相对简单的CRUD工作。
出于性能原因,一些更复杂的查询内容由后端中的更复杂的查询处理。
在我们的案例中使用Spring的优点是我们可以拥有依赖于国家/语言的实例,这些实例在Spring
Proxy类的后面。根据会话中的用户,在进行呼叫时将使用正确的国家(地区)/语言实现。
事务管理几乎是透明的,可以在运行时异常上回滚。我们尽可能使用未检查的异常。我们曾经做过检查异常,但是随着Spring的引入,我看到了非检查异常的好处,只有在可以的情况下才处理异常。它避免了很多样板“捕获/抛出”或“抛出”的东西。
抱歉,它比您的帖子短,希望您发现这个有趣的话题…
有人知道MSBuild的SonarQube扫描器是作为构建的一部分进行扫描并只将结果发回给SonarQube,还是EXE正在检测,我们可以将工件发送到Linux机器上的SonarQube进行分析,类似于使用sonar-scanner-cli扫描java工件的方式?
我对web应用程序向微服务的发散点感到困惑--它是在url级别还是模型级别?举个例子,假设我有一个单片应用程序,它提供3个页面。假设每个页面都有一个单独的用法,我想用它们自己的微服务来支持它们。下面哪一种是实现基于微服务的体系结构的正确方法: 我创建了三个不同的应用程序(微服务),每个都包含一个页面的(路由、控制器、模型、模板)。然后根据哪个页面被请求,我将请求路由到那个特定的应用程序。这意味着从
我做了一个Android应用程序,可以在Google Play上使用。现在我想添加一些更多的格式到我的应用程序描述(例如,缩进,链接,列表..)。但我找不到任何网站在可能的格式列出。谷歌帮助页面也不能帮助我在这个主题。有很多不同的格式,我真的不知道该使用哪一种(例如,HTML或wiki格式…) 我可以通过反复试验来测试它,但这需要一些时间,因为Google Play只会在2-3小时后刷新。在我测试
谷歌的Play Store在应用程序描述中支持相当多的标记。对于华为的AppGallery来说,这是怎么回事?我在任何地方都找不到这方面的信息。 我确实尝试过使用和,但它们都显示为纯文本(标签可见)--在AppGallery应用程序和其网站上都是如此。
这是一个有点开放性的问题,但是,制作一个好的可扩展电子应用程序的好方法是什么?VSCode、Atom和许多其他软件都支持扩展,但它们的代码库太大,我无法理解到底发生了什么。我对Jupyterlab感到非常惊讶,据他们说,它包含一个小小的核心,而其他一切都只是它上面的扩展。所以我想知道如何构建这些应用程序。 我的具体问题是: 是否有创建可扩展架构的最佳实践 电子部分是如何“识别”延伸的?怎么装的?什
过去,我在玩Node。js只在我的本地机器上,所以我只有使用单进程Node的经验。js应用程序。现在,我想创建一个可以在web上发布的web应用程序。 这个web应用程序有点像多人游戏——使用Socket。IO用于客户端-服务器通信,Express用于处理HTTP请求,grunt用于任务管理,等等——我希望使用其他NPM包来处理各种任务。 我想将此应用程序的架构设计为 < li >实现水平可伸缩性