首页 文章

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

提问于
浏览
144

Let's share Java based web application architectures!

Web应用程序有许多不同的体系结构,这些体系结构将使用Java实现 . 这个问题的答案可以作为各种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,如 AccountShoppingCart 等 .

商业

与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所以我们不要't have to do transaction demarcation our self' . 基本上发生的事情是我们在输入SLSB方法时启动事务并在退出方法之前立即提交(或回滚它) . 除了默认值,它还需要除此之外的任何东西 .

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

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

演讲

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

该层调用业务层管理器中的方法,以执行用户请求的操作,并接收要在网页中显示的信息 . 有时,从业务层收到的信息的复杂类型不如 Stringint egers,其他时候JPA entities .

与建筑的利弊

优点

  • 拥有与在此层中执行持久性的特定方式相关的所有内容,这意味着我们可以将JPA交换为其他内容,而无需在业务层中重写任何内容 .

  • 如果我们找到更好的东西,我们可能会这样做 .

  • 让EJB容器管理事务边界很好 .

  • 使用Servlet的JPA很容易(首先),并且这些技术在许多服务器中得到广泛使用和实现 .

  • 使用Java EE可以让我们更轻松地使用load balancingfail over创建高可用性系统 . 我们认为我们必须拥有这两者 .

缺点

  • 您可以使用JPAstore通常使用JPA实体类上的 @NamedQuery 注释将查询用作命名查询 . 如果您尽可能多地与持久性类中的持久性相关,就像在我们的体系结构中一样,这将分散您可能发现查询以包括JPA实体的位置 . 概述持久性操作并因此难以维护将更加困难 .

  • 我们将JPA实体作为持久层的一部分 . 但是 AccountShoppingCart ,它们不是真正的商业对象吗?它以这种方式完成,因为您必须触摸这些类并将它们转换为JPA知道如何处理的实体 .

  • JPA实体(也是我们的业务对象)的创建类似于数据传输对象(DTO 's), also known as Value Objects (VO') . 这导致anemic domain model,因为除了访问器方法之外,业务对象没有自己的逻辑 . 所有逻辑都由业务层中的经理完成,从而产生更多程序化的编程风格 . 它's not good object oriented design, but maybe that'不是问题吗? (毕竟面向对象并不是唯一能够提供结果的编程范例 . )

  • 使用EJB和Java EE引入了一些复杂性 . 我们可以_411402_吨纯粹是Tomcat) .

  • 使用Servlet的JPA存在很多问题 . 使用Google获取有关这些问题的更多信息 .

  • 由于在退出业务层时关闭了事务,我们可以在表示层内部使用't load any information from JPA entities which is configured to be loaded from the database when it'(使用 fetch=FetchType.LAZY ) . 它会触发异常 . 在返回包含这些类型字段的实体之前,我们必须确保调用相关的getter . 另一种选择是使用Java持久性查询语言(JPQL)并执行 FETCH JOIN . 然而,这两个选项都有点麻烦 .

10 回答

  • 1

    Ideal Java Based Web Development Technologies Today.

    网页层:

    HTML CSS Ajax JQuery

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

    玩框架

    业务逻辑/服务层:

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

    XML / JSon数据转换层:

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

    持久层:

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

  • 9

    Web Application Architecture中的组件包括:

    1:浏览器:客户端交互

    HTML
            JavaScript
            Stylesheet
    

    2:互联网

    3:Webserver

    CSS
            Image
            Pages(Java render )
    

    4:Application Server

    App Webapp (Java interaction)
            Others WebApps
    

    5:数据库服务器

    Oracle, SQL, MySQL
    

    6:数据

  • 0

    Here is one more web architecture I have worked on:

    一个主要要求是应用程序应支持移动设备/其他设备 . 对于技术选择的变化,应用程序也应该是可扩展的或灵活的 .

    Presentation Tier:

    • JSP / JQuery(客户端MVC)

    • 原生Android

    • 原生iPhone

    • 移动网络(HTML5 / CSS3 /响应式设计)

    • Spring REST控制器(可以更改为JAX-RS)

    Business Service Tier:

    Spring @Service(可以更改为无状态EJB)

    Data Access Tier:

    Spring @Repository(可以更改为无状态EJB)

    Resource Tier:

    Hibernate(JPA)实体(可以更改为任何ORM)

    您可以在该架构here之后找到有关该书的更多信息 .

  • 3

    有点不同,我想在这里声称更多的模块化Java架构 . 我们有:

    • Spring WS / Rest / JSP前端

    • 用于业务服务逻辑的Spring MVC,包含表示层逻辑以及Spring事务

    • 组件服务通信接口,通过业务服务查找EJB . EJB设置自己的事务边界,可以加入Spring事务 .

    • 组件服务实现,再次是Spring组件

    • 集成层,用于数据库集成的MyBatis,用于Web服务集成的Spring WS,用于其他服务的其他集成技术

    • 大型机,数据库,其他服务器的其他服务......

    除了上述内容之外,我们还有共享库模块,它是所有服务的通用功能提供者 .

    使用不同的层允许我们完全去耦和我们需要的模块化 . 我们还能够充分利用Java EE和Spring的强大功能 . 例如,如果需要,没有什么能阻止我们使用JSF作为前端 .

    与OP的示例架构相比,我认为这可以被描述为具有四个主要层而不是三个,尽管有一个扭曲 .

  • 19

    我曾经在使用那种严格的经理模式的项目上工作过 . 从历史上看,我是刚性层次结构的巨大支持者,一切都适合整齐的盒子 . 随着我职业生涯的进步,我发现在很多情况下都会被迫 . 我相信对应用程序设计采用更敏捷的思维方式可以产生更好的产品 . 我的意思是创建一组解决手头问题的类 . 而不是说“你为此 Build 了一个经理吗?”

    我正在开发的当前项目是一个结合了Spring MVC和RestEasy JSON / Ajax调用的Web应用程序 . 在我们的控制器中嵌入的服务器端是一个合理的基于外观的数据层JPA / Hibernate用于直接数据库访问,一些EJB访问和一些基于SOAP的Web服务调用 . 将所有这些结合在一起的是一些自定义java控制器代码,它确定将序列化为JSON并返回到客户端的内容 .

    我们几乎没有时间尝试创建一些统一模式,而是选择采用Unix设计理念的“更糟糕更好”的理念 . 因为它更好地在线条之外着色并且构建一些合理的,快速的,而不是构建符合一系列严格设计要求的东西 .

  • 7

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

    • 前端:Tapestry(旧项目3个,新项目5个)

    • 业务层: Spring 天

    • DAO:Ibatis

    • 数据库:Oracle

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

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

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

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

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

  • 4

    这是我的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

  • 18

    我们在项目中遵循的是:

    Front end Technology

    • AngularJS

    • HTML5

    • css3

    • Javascript

    • Bootstrap 3

    API

    • REST

    • JERSEY(JAX-RS)

    • REST ASSURED

    • SPRING BOOT

    • Jackson

    • Spring 天的安全

    Business Logic

    • Spring 天数据

    • SPRING数据MongoDB

    Data base

    • MongoDB

    Server (For caching)

    • redis
  • 0

    我们仍在使用通常的Struts-Spring-Hibernate堆栈 .

    对于未来的应用程序,我们正在研究具有Flex前端的Spring Web Flow Spring MVC Hibernate或Spring Hibernate Web服务 .

    我们的架构的一个独特特征是模块化 . 我们有许多模块,有些模块在数据库中以3到30个表开始 . 大多数模块包括业务和Web项目 . 当Web保存表示逻辑时,业务项目保持业务和持久性逻辑 .
    在逻辑层面上,有三个层:业务,持久性和表示 .
    依赖关系:
    演示取决于业务和持久性 .
    持久性取决于业务 .
    业务不依赖于其他层 .

    大多数业务项目有三种类型的接口(注意:不是GUI,它是一个程序化的java接口层) .

    • 演示文稿用作客户端的接口

    • 其他模块作为模块客户端时使用的接口 .

    • 可用于模块管理目的的接口 .

    通常,1扩展2.这样,很容易将模块的一个实现替换为另一个 . 这有助于我们采用不同的客户并更轻松地集成 . 有些客户只会购买某些模块,我们需要整合他们已有的功能 . 由于接口和实现层是分开的,因此很容易为特定客户端推出ad-hock模块实现,而不会影响依赖模块 . Spring Framework可以轻松注入不同的实现 .

    我们的业务层基于POJO . 我观察到的一个趋势是这些POJO类似于DTO . 我们受anaemic domain model的影响 . 我不太清楚为什么会发生这种情况,但这可能是由于我们许多模块的问题域的简单性,大多数工作是CRUD或者由于开发人员更喜欢将逻辑放在其他地方 .

  • 2

    恕我直言,我们大多数人都有一个共同点 . 至少在后端,我们有一些形式的IOC / DI容器和一个持久性框架 . 我个人使用Guice和Mybatis . 不同之处在于我们如何实现视图/ UI /表示层 . 这里有两个主要选项(可能更多) . 基于动作(映射到控制器的URL)和基于组件 . 目前我正在使用基于组件表示层(使用wicket) . 它完美地模仿了我使用组件和事件而不是URL和控制器的桌面环境 . 我目前正在寻找一个原因,我应该迁移到这种URL控制器类型的架构(这就是我在这个页面上的结果) . 为什么炒作关于RESTful和无状态架构 .

    简而言之:我在Guice IOC容器上使用面向组件的框架编写有状态Web应用程序,并使用Mybatis将数据放入关系数据库 .

相关问题