描述用于Java Web应用程序的体系结构? [关闭]

问题

让我们分享基于Java的Web应用程序架构!
Web应用程序有许多不同的体系结构,这些体系结构将使用Java实现。这个问题的答案可以作为各种Web应用程序设计的库,各有利弊。虽然我意识到答案是主观的,但我们尽量做到客观,并激励我们列出的利弊。

使用你喜欢的详细程度来描述你的体系结构。为了使你的答案具有任何价值,你至少必须描述你所描述的架构中使用的主要技术和想法。最后但并非最不重要的是,我们应该使用你的架构吗?

我会开始......

#架构概述

我们使用基于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注释成为aStateless Session Bean(SLSB)。每个SLSB称为amanagerand,例如,管理器可以是注释的类,如上所述,称为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方法时启动事务并在退出方法之前立即提交(或回滚它)。这是约定优于配置的一个例子,但是除了默认值,我们还没有任何需要。

以下是Sun的Java EE 5教程如何解释Enterprise JavaBeans(EJB)的Required transaction attribute

如果客户端在事务中运行并调用企业bean的方法,则该方法在客户端的事务中执行。如果客户端未与事务关联,则容器在运行该方法之前启动新事务。 Required属性是使用容器管理的事务划分运行的所有企业bean方法的隐式事务属性。除非需要覆盖其他事务属性,否则通常不会设置Required属性。由于事务属性是声明性的,因此你可以在以后轻松更改它们。

介绍

我们的演示层负责......演示!它负责用户界面,并通过构建HTML页面并通过GET和POST请求接收用户输入来向用户显示信息。我们目前正在使用oldServlet的Java Server Pages(JSP)组合。

该层调用业务层管理器中的方法来执行用户请求的操作并接收要在网页中显示的信息。有时,从业务层收到的信息类型较少,如Stringint,以及其他时间JPA entities

#与架构的优点和缺点

##优点

  • 让所有与在此层中执行持久性的特定方式相关的内容仅意味着我们可以将JPA交换为其他内容,而无需在业务层中重写任何内容。
  • 我们很容易将表示层交换为其他内容,如果我们找到更好的东西,我们很可能会这样做。
  • 让EJB容器管理事务边界很好。
  • 使用Servlet的JPA很容易(首先),并且这些技术在许多服务器中得到广泛使用和实现。
  • 使用Java EE可以使我们更容易创建具有负载平衡和故障转移的高可用性系统。我们认为我们必须拥有这两者。

##缺点

  • 使用JPA可以通过在JPA实体类上使用@NamedQuery注释将常用查询存储为命名查询。如果你尽可能多地与持久性类中的持久性相关,就像在我们的体系结构中一样,这将分散你可能发现查询以包括JPA实体的位置。概述持久性操作并因此难以维护将更加困难。
  • 我们将JPA实体作为持久层的一部分。但是Account和ShoppingCart,它们不是真正的业务对象吗?它以这种方式完成,因为你必须触摸这些类并将它们转换为JPA知道如何处理的实体。
  • JPA实体(也是我们的业务对象)被创建为数据传输对象(DTO),也称为值对象(VO)。这导致了贫血领域模型,因为除了访问者方法之外,业务对象没有自己的逻辑。所有逻辑都由业务层中的经理完成,从而产生更多程序化的编程风格。这不是一个好的面向对象设计,但也许这不是一个问题? (毕竟面向对象并不是唯一能够提供结果的编程范例。)
  • 使用EJB和Java EE引入了一些复杂性。而且我们不能纯粹使用Tomcat(添加EJB微容器不仅仅是Tomcat)。
  • 使用Servlet的JPA存在很多问题。使用Google获取有关这些问题的更多信息。
  • 当退出业务层时事务处于关闭状态时,我们无法从JPA实体加载任何信息,这些信息配置为在表示层内部需要时(使用fetch = FetchType.LAZY)从数据库加载。它会触发异常。在返回包含这些类型字段的实体之前,我们必须确保调用相关的getter。另一种选择是使用Java持久性查询语言(JPQL)并执行FETCH JOIN。然而,这两个选项都有点麻烦。

#1 热门回答(18 赞)

好的,我会做一个(更短的):

  • 前端:Tapestry(旧项目3个,新项目5个)
  • 业务层:春天
  • DAO:Ibatis
  • 数据库:Oracle

我们使用Sping事务支持,并在进入服务层时启动事务,向下传播到DAO调用。服务层具有最多的商务模型知识,DAO执行相对简单的CRUD工作。

出于性能原因,一些更复杂的查询内容由后端中更复杂的查询处理。

在我们的例子中使用Spring的优点是我们可以使用依赖于国家/语言的实例,它们位于Spring Proxy类之后。根据会话中的用户,在进行呼叫时使用正确的国家/语言实现。

事务管理几乎是透明的,回滚运行时异常。我们尽可能使用未经检查的例外。我们曾经做过检查异常,但是随着Spring的介绍,我看到了未经检查的异常的好处,只有在可以的情况下才处理异常。它避免了很多样板"捕获/重新抛出"或"抛出"的东西。

对不起,它比你的帖子短,希望你发现这个有趣......


#2 热门回答(18 赞)

今日理想的基于Java的Web开发技术。

#Web Layer:

HTML CSS Ajax JQuery

#RESTFul Web控制器/动作/请求处理层:

玩框架

#业务逻辑/服务层:

尽可能长时间使用Pure Java Code。可以在这里进行Web服务的融合。

#XML / JSon数据转换层:

XMLTool(在Google Code上搜索),JSoup,Google GSon,XStream,JOOX(在Google Code上搜索)

#Persistence Layer:

CRUD:JPA或SienaProject或QueryDSL /复杂查询:JOOQ,QueryDSL


#3 热门回答(9 赞)

这是我的5美分

介绍

Android,Angular.JS WebClient,OAUTHv2

API

REST,Jersey(JAX-RS),Jackson(JSON de- / serialization),DTO对象(不同于业务逻辑模型)

商业逻辑

用于DI和事件处理的Spring。模型对象的DDD-ish方法。在工作模块中使用SQS卸载更长时间运行的作业。

DAO

具有Spring JDBC模板的存储库模型,用于存储实体。 Redis(JEDIS)用于排行榜,使用有序列表。令牌存储的Memcache。

##数据库

MySQL,Memcached,Redis