为什么我要在 Java/Spring 上使用 Scala/Lift?

我知道这个问题有点开放,但是我一直在研究 Scala/Lift 作为 Java/Spring 的替代品,我想知道 Scala/Lift 在这方面的真正优势是什么。从我的角度和经验来看,Java 注释和 Spring 确实最大限度地减少了应用程序的编码量。Scala/Lift 在这方面有所改进吗?

43579 次浏览

只是为了好玩,也为了学习新的编程方法。

扩展你的知识总是值得努力的:)我刚开始学习 Scala,它影响了我如何编写普通的 Java,我可以说到目前为止它是非常有益的。

我是从 Java 背景开始使用 Lift 和 Scala 的,所以这不是我个人的经验,但是我知道很多 Lift 开发人员发现 Scala 是一种比 Java 更简洁和高效的语言。

让我们假设我们在 Scala 和 Java 中感到同样舒适,并忽略(巨大的)语言差异,除非它们与 Spring 或 Lift 有关。

Spring 和 Lift 在成熟度和目标方面几乎是截然相反的。

  • 春天比电梯大五岁
  • Lift 是单一的,只针对 web; Spring 是模块化的,既针对 web,也针对“常规”应用
  • Spring 支持过多的 JavaEE 特性; Lift 忽略了这些特性

一句话,Spring 是重量级的,Lift 是轻量级的。有了足够的决心和资源,你可以把它的头,但你需要一个 很多的两个。

在使用这两种框架之后,下面是一些具体的不同之处,它们一直在我脑海中挥之不去。这不是一个详尽的列表,我无论如何也编译不出来。我觉得最有意思的是。

  1. 查看哲学

    Lift 鼓励在代码片段/操作方法中放置一些视图材料。特别是代码片段将会使用程序生成的表单元素、 <div><p>等。

    这是强大而有用的,特别是因为 Scala 有一个内置的语言级 XML 模式。可以在 Scala 方法中内联编写 XML,包括括括号中的变量绑定。对于非常简单的 XML 服务或服务模型来说,这可能是令人愉快的——您可以在一个非常简洁的文件中快速生成一套 HTTP 响应操作,而不需要模板或大量相关配置。缺点是复杂性。视图和逻辑之间要么有一个模糊的关注点分离,要么没有分离,这取决于你走了多远。

    相比之下,Web 应用程序定期使用 Spring 强制将视图和其他所有应用程序分离开来。我认为 Spring 支持多个模板引擎,但我只在严肃的场合使用过 JSP。用 JSP 做一个受 Lift 启发的“模糊 MVC”设计将是疯狂的。对于大型项目来说,这是一件好事,因为花在阅读和理解上的时间太多了。

  2. 对象关系映射器选择

    升降机内置的 ORM 是“映射器”。即将出现一个叫做“ Record”的替代品,但我认为它仍然被认为是前阿尔法。LiftWebBook 有关于使用 Mapper 和 JPA 的章节。

    Lift 的 克鲁迪化特性虽然很酷,但只能用于 Mapper (而不是 JPA)。

    当然,Spring 支持 全套标准和/或成熟的数据库技术。关键词是“支持”。理论上,您可以在 Lift 中使用任何 JavaORM,因为您可以从 Scala 调用任意 Java 代码。但 Lift 实际上只支持 Mapper 和(程度小得多的) JPA。此外,在 Scala 中使用重要的 Java 代码目前并不像人们想象的那样无缝; 使用 Java ORM,您可能会发现自己要么在任何地方使用 Java 和 Scala 集合,要么将所有集合转换为 Java 组件。

  3. 配置

    Lift 应用程序的配置几乎完全通过一个方法,一个应用程序范围的“ Boot”类。换句话说,配置是通过 Scala 代码完成的。这对于有简短配置的项目来说是完美的,而且当进行配置的人对编辑 Scala 感到舒服的时候。

    Spring 在配置方面非常灵活。许多 conf 选项可以通过 XML 配置或注释来驱动。

  4. 文件

    Lift 的文档还很年轻,Spring 的文档已经很成熟了,没什么可争的。

    由于 Spring 的文档已经组织得很好,并且很容易找到,我将查看我为 Lift 找到的文档。Lift 文档基本上有4个来源: LiftWeb BookAPI 文件、 LiftWeb 的 谷歌小组和“ 开始”。还有一套很好的代码示例,但我不会把它们称为“文档”本身。

    API 文档不完整。LiftWeb Book 已经在树上出版,但它也可以在网上免费获得。它真的很有用,尽管它的明确的说教风格有时会激怒我。教程有点长,合同有点短。Spring 有一个合适的手册,而 Lift 没有。

    但是 Lift 确实有一组很好的例子。如果您熟悉 Lift 代码和示例代码(而且您已经非常熟悉 Scala) ,那么您可以在相当短的时间内解决问题。

这两个框架都很有吸引力,你可以选择其中一个并且做得很好。

我不想把你的世界搞得一团糟。但是你可以在一个应用程序中使用 Scala、 Java、 Lift、 Spring,而且不会有问题。

我建议你检查一下播放框架,它有一些非常有趣的想法,并且支持 Java 和 Scala 的开发

我不得不说,我强烈反对 Dan LaRocque 的回答。

电梯不是整体的。它是由离散元素构成的。它不忽略 J/EE 元素,它支持 JNDI、 JTA、 JPA 等等。事实上,你没有被迫使用 J/EE 的这些元素是 Lift 的模块化设计的一个强有力的指示。

  • Lift 的观点是“让开发者决定”Lift 提供了一种不允许在视图中使用任何逻辑代码的模板机制,一种基于执行 Scala 代码和 Scala 的 XML 文本的视图机制,以及一种基于 加速的视图机制。如果您选择 XML 模板机制,那么您可以选择业务逻辑中有多少标记(如果有的话)。Lift 的视图分离比 Spring 提供的任何视图分离都要强,因为无法在 Lift 的 XML 模板中表达任何业务逻辑。
  • Lift 的对象持久化哲学是“让开发者决定”Lift 有一个 Mapper,它是一个 ActiveRecord 样式的对象关系映射器。它可以完成小项目的工作。升降支撑 JPA。Lift 有一个 Record 抽象,支持对象在关系数据库中进出,在 NoSQL 存储中进出(Lift 包括对 CouchDB 和 MongoDB 的本地支持,但是适配器层只有几百行代码,所以如果你想要 Cassandra 或者其他东西,不需要太多工作就可以得到它)基本上,Lift the Web Framework 不依赖于对象如何具体化到会话中。此外,会话和请求周期是打开的,因此将事务挂钩插入到请求/响应周期是很简单的。
  • Lift 的理念是“服务器团队需要了解一种语言,而不是多种语言。”这意味着配置是通过 Scala 完成的。这意味着我们不必在 XML 语法中实现40% 的 Java 语言结构来创建灵活的配置选项。这意味着编译器语法和类型检查配置数据,这样在运行时就不会得到任何奇怪的 XML 解析或不正确的数据。这意味着您不必让 IDE 基于所使用的库来理解您正在使用的注释的细节。
  • 是的,Lift 的文档不是它的强项。

既然如此,让我来谈谈 Lift 的设计理念。

我写 网络框架宣言之前,我开始写电梯。Lift 在很大程度上达到了这些目标,而且比我所知道的任何其他 Web 框架都要高。

Lift 的核心目标是抽象出 HTTP 请求/响应周期,而不是围绕 HTTP 请求放置对象包装器。在实际层面上,这意味着用户可以采取的大多数操作(提交表单元素、执行 Ajax 等)都由浏览器中的 GUID 和服务器上的函数表示。当 GUID 作为 HTTP 请求的一部分显示时,将使用提供的参数应用(调用)该函数。因为 GUID 很难预测,而且是特定于会话的,所以使用 Lift 进行重放攻击和许多参数篡改攻击要比大多数其他 web 框架(包括 Spring)困难得多。这也意味着开发人员的工作效率更高,因为他们关注用户操作和与用户操作相关的业务逻辑,而不是打包和解包 HTTP 请求。例如,接受或拒绝 FourSquare 好友请求的代码:

ajaxButton("Accept", () => {request.accept.save;
SetHtml("acceptrejectspan", <span/>}) ++
ajaxButton("Reject", () => {request.reject.save;
SetHtml("acceptrejectspan", <span/>})

就这么简单。因为在创建函数时,FriendRequest 在作用域中,所以函数会关闭作用域... ... 不需要暴露好友请求的主键或者做其他事情... ... 只需定义按钮的文本(它可以本地化,也可以从 XHTML 模板中提取,或者从本地化模板中提取)以及按下按钮时要执行的函数。Lift 负责分配 GUID,设置 Ajax 调用(通过 jQuery 或 YUI,是的,你可以添加自己喜欢的 JavaScript 库) ,自动重试和后退,通过对 Ajax 请求进行排队来避免连接匮乏,等等。

因此,Lift 和 Spring 之间的一大区别在于 Lift 与功能相关的 GUID 哲学具有更好的安全性和更好的开发人员生产力的双重好处。GUID-> 函数关联已经被证明是非常持久的... 同样的结构适用于普通形式、 ajax、 comet、多页面向导等。

Lift 的下一个核心部分是尽可能长时间地保持高级抽象。在页面生成方面,这意味着将页面构建为 XHTML 元素,并将页面保持为 XHTML,直到响应流之前。这样做的好处是可以避免跨网站脚本错误,可以在页面组成后将 CSS 标签移到页面的头部,将脚本移到页面的底部,还可以根据目标浏览器重写页面。在输入端,URL 可以重写,以类型安全的方式提取参数(查询和路径参数) ,高级别的安全检查数据可以在请求周期的早期处理。例如,下面是如何定义 REST 请求的服务:

  serve {
case "api" :: "user" :: AsUser(user) :: _ XmlGet _ => <b>{user.name}</b>
case "api" :: "user" :: AsUser(user) :: _ JsonGet _ => JStr(user.name)
}

使用 Scala 的内置模式匹配,我们匹配一个传入的请求,提取路径的第三部分,得到与该值对应的 User,甚至应用访问控制检查(当前会话或请求是否有权访问给定的 User 记录)。因此,在 User 实例命中应用程序逻辑之前,已经对其进行了审查。

有了这两个核心部件,Lift 在安全性方面具有巨大的优势。为了让你对 Lift 的安全性有个大概的了解,而且不会妨碍它的功能,为雅虎做安全工作的 拉斯马斯 · 勒道格对 FourSquare (Lift 的海报式网站之一)有这样的评价:

四星级到@foursquare-1st 站点,在一段时间内,我仔细看了看,没有一个单一的安全问题(我可以找到)-http://twitter.com/rasmus/status/5929904263

当时,FourSquare 有一个工程师负责编写代码(并不是说@harryh 不是一个超级天才) ,他的主要工作是重写 FourSquare 的 PHP 版本,同时应对每周流量翻倍的问题。

Lift 的安全重点的最后一部分是 SiteMap。它是一个统一的访问控制、站点导航和菜单系统。开发人员使用 Scala 代码(例如 If(User.loggedIn _)If(User.superUser _))为每个页面定义访问控制规则,这些访问控制规则在页面呈现开始之前应用。这很像 Spring Security,只不过它是从项目一开始就固定下来的,而且访问控制规则与应用程序的其他部分是统一的,所以当 URL 发生变化或者计算访问控制变化的方法发生变化时,您不需要使用 XML 来更新安全规则。

到目前为止,Lift 的设计理念为您提供了嵌入式访问控制的好处、对 OWASP 前10大安全漏洞的抵抗力、更好的 Ajax 支持以及比 Spring 更高的开发效率。

但 Lift 也为您提供了所有 Web 框架中最好的 Comet 支持。这就是为什么 Novell 选择 Lift 来驱动他们的 脉搏产品,下面是 Novell 对 Lift 的评价:

Lift 是一种网络框架 使您作为开发人员能够 把注意力集中在大局上。 强有力的,富有表现力的打字 更高层次的特性,比如 内置的 Comet 支持允许您 专注于创新而不是 管道工程,建造一个丰富的,实时的 像 Novell Pulse 这样的网络应用程序 需要一个具有 掀开被子。

因此,Lift 不仅仅是另一个我也 MVC 框架。这是一个框架,背后有一些核心设计原则,已经非常成熟。它是一个提供安全性和开发人员生产力双重优势的框架。Lift 是一个内置在层中的框架,它让开发人员根据自己的需求做出正确的选择... 视图生成的选择,持久性的选择等等。

Scala 和 Lift 给开发人员提供了比组成 Spring 的 XML、注释和其他习惯用法更好的体验。

我在最近的一个网络项目中非常关注 Lift 的使用,并不是 SpringMVC 的忠实粉丝。我没有使用最新的版本,但是早期版本的 Spring MVC 让您跳过了许多障碍来使 Web 应用程序运行。我几乎是推销 Lift,直到我看到 Lift 可以非常会话依赖,需要“粘性会话”才能正常工作。节选自 http://exploring.liftweb.net/master/index-9.html#sec:Session-Management

直到有一个标准的会话复制技术,您仍然可以 集群你的应用程序使用“粘性会话”。这意味着所有 与 HTTP 会话相关的请求必须由相同的 集群节点

因此,一旦需要一个 Session,用户就必须是该节点的 pin。这就产生了对智能负载平衡的需求,并影响了伸缩性,这使 Lift 无法成为我的解决方案。我最终选择了 http://www.playframework.org/,并感到非常高兴。到目前为止,游戏一直是稳定可靠的,并且非常容易操作。

在我看来,想象力才是最重要的。

假设你想写一个应用程序。如果你是一个优秀的开发者,这个应用程序应该已经在你的脑海中构建好了。下一步是通过代码发现它是如何工作的。为了做到这一点,您需要通过一个函数传递想象中的应用程序,该函数将其转换为现实世界中的应用程序。那个函数是一种编程语言。那么

Real app = programming language (imagined app)

所以语言选择很重要。框架也是。这里有很多聪明的人会建议你选择什么,但最终,能够最好地翻译你的想象力的语言/框架应该是你的选择。所以两者都是原型,然后做出你的选择。

至于我,我正在慢慢学习 Scala 和 Lift,并且很喜欢它。

但是主要的问题是我们不能把弹簧和升力相比较。Lift 基本上用作 UI 框架,Spring 用作 DI 框架。
如果你正在开发的网络应用程序,有这么多的后端,确保你可以使用电梯。
但是如果你开发的网络应用程序有一些系列的后端,你肯定需要去春天。