为什么我会使用Java / Spring的Scala / Lift?

我知道这个问题有点儿开放,但我一直在寻找Scala / Lift作为Java / Spring的替代品,我想知道Scala / Lift有什么优势。 从我的angular度和经验来看,Java Annotations和Spring确实可以最大限度地减less您为应用程序执行的编码量。 Scala / Lift会改进吗?

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

在成熟和目标方面,“spring与升迁”几乎是截然相反的。

  • spring比电梯大五岁
  • 电梯是整体的,只针对networking; Spring是模块化的,针对Web和“常规”应用程序
  • Spring支持大量的Java EE特性; 电梯忽略那些东西

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

在使用这两个框架之后,在我脑中留下了具体的差异。 这不是一个详尽的清单,我不能编译。 我觉得最有意思的是…

  1. 观看哲学

    电梯鼓励在片段/动作方法中放置一些视图材料。 代码段代码尤其会被编程生成的表单元素, <div> s, <p> s <p>

    这是强大的和有用的,尤其是因为Scala具有内置的语言级XML模式。 我们可以在Scala方法内联编写XML,包括花括号中的variables绑定。 对于非常简单的XML服务或服务模型,这可能是件愉快的事情 – 您可以在一个精彩简洁的文件中敲出一整套HTTP响应操作,而不需要模板或更多的相关configuration。 缺点是复杂性。 根据你走多远,在视图和逻辑之间要么模糊分离,要么不分离。

    相比之下,定期使用Spring for webapps强化视图和其他所有东西之间的强烈分离。 我认为Spring支持几个模板引擎,但是我只使用了任何严肃的JSP。 用JSP提升灵感的“模糊MVC”devise将是疯狂的。 对于大型项目来说,这是一件好事,只要阅读和理解的时间就可以压倒一切。

  2. 对象关系映射器select

    Lift的内置ORM是“Mapper”。 有一个即将到来的替代品称为“logging”,但我认为它仍然被认为是前阿尔法。 LiftWeb书籍有使用Mapper和JPA的章节。

    Lift的CRUDifyfunction很酷,只适用于Mapper(而不是JPA)。

    当然,Spring支持全面的标准和/或成熟的数据库技术 。 操作词有“支持”。 理论上讲,你可以使用任何带有Lift的Java ORM,因为你可以从Scala调用任意的Java代码。 但是Lift只支持Mapper和(在很小的程度上)JPA。 此外,在Scala中处理非平凡的Java代码目前并不像想象的那么无缝, 使用Java ORM,您可能会发现自己既可以使用Java和Scala集合,也可以将所有集合转换为Java组件。

  3. 组态

    提升应用程序几乎完全通过应用程序范围的“引导”类的方法进行configuration。 换句话说,configuration是通过Scala代码完成的。 这对于configuration简单的项目来说是非常完美的,而当进行configuration的人员可以轻松编辑Scala时。

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

  4. 文档

    Lift的文件是年轻的。 Spring的文档相当成熟。 没有比赛。

    由于Spring的文档已经很好的组织起来,而且很容易find,我将回顾一下我在Lift上find的文档。 Lift文档基本上有四个来源: LiftWeb书籍 , API文档 ,LiftWeb的Google小组和“ 入门 ”。 还有一套很好的代码示例,但我不会称之为“文档”本身。

    API文档不完整。 LiftWeb图书已经发布在树上,但也可以在线免费获取。 这是非常有用的,虽然它的决定性的教学风格有时激怒了我。 在教程和合同上有点长。 spring有一个适当的手册,哪个电梯缺乏。

    但是Lift有一些很好的例子。 如果你很喜欢阅读电梯代码和示例代码(而且你已经知道了Scala),那么你可以按照相当短的时间来完成工作。

这两个框架是令人信服的。 有一个广泛的应用程序,你可以select,做得很好。

我必须说,我坚决不同意丹·拉罗克的回答。

电梯不是一个整体。 它由离散元素组成。 它不会忽略J / EE元素,它支持诸如JNDI,JTA,JPA等等。您不必强迫使用这些J / EE元素,这是Lift的模块化devise的强有力的performance。

  • Lift的观点哲学是“让开发者决定”。 Lift提供的模板机制不允许视图中的任何逻辑代码,基于执行Scala代码和Scala的XML文字的视图机制,以及基于Scalate的视图机制。 如果您selectXML模板机制,那么您可以select多less(如果有的话)标记属于您的业务逻辑。 Lift的视图分离比Spring提供的更强大,因为您无法在Lift的XML模板中expression任何业务逻辑。
  • Lift的对象↔坚持的理念是“让开发者决定”。 Lift有一个ActiveRecord风格的对象关系映射器Mapper。 它完成了小项目的工作。 提升支持JPA。 Lift有一个Record抽象,支持将对象从关系数据库进出数据库,进出NoSQL存储(Lift包括对CouchDB和MongoDB的本地支持,但适配器层是几百行代码,所以如果你想要Cassandra或还有一些其他的东西并不是很多。)基本上,提升Web框架不依赖于对象如何物化到一个会话中。 此外,会话和请求周期是开放的,以便将事务挂接插入请求/响应周期是简单的。
  • Lift的理念是“服务器团队需要了解一种语言,而不是多种语言”。 这意味着configuration是通过Scala完成的。 这意味着我们不必在XML语法中实现40%的Java语言结构来创build灵活的configuration选项。 这意味着编译器语法和types检查configuration数据,所以你不会在运行时得到任何奇怪的XMLparsing或不正确的数据。 这意味着您不必让IDE根据您正在使用的库来了解您正在使用的注释的详细信息。
  • 是的,Lift的文档不是它的强项。

有鉴于此,让我来谈一谈关于Lift的devise理念。

在我开始编写Lift之前,我编写了Web Framework Manifesto 。 在很大程度上,对于我所知道的任何其他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在创build函数的时候处于范围之内,所以函数closures了范围……不需要公开好友请求的主键或者做任何事情……只要定义button的文本(它可以是本地化的,也可以是从XHTML模板中提取的,也可以是从本地化的模板中提取的)以及按下button时执行的function。 Lift负责分配GUID,设置Ajax调用(通过jQuery或YUI,是的,你可以添加你自己喜欢的JavaScript库),自动重试退避,通过排队Ajax请求避免连接饿死等。

所以,Lift和Spring之间的一个很大的区别就是Lift与GUID相关的哲学有着更好的安全性和更好的开发效率。 GUID – >函数关联已经被certificate是非常持久的…相同的构造适用于正常forms,ajax,彗星,多页面向导等。

Lift的下一个核心部分是尽可能保持高层次的抽象。 在页面生成方面,这意味着将页面构build为XHTML元素并将页面保持为XHTML,直到stream式传输响应。 其好处是可以抵抗跨站点脚本错误,可以在页面编写完成后将CSS标签移动到页面底部并将脚本移动到页面底部,还可以根据目标浏览器重写页面。 在input端,URL可以被重写,以便以types安全的方式提取参数(包括查询和path参数),高级的安全检查数据可以在请求周期的早期处理。 例如,以下是如何定义REST请求的服务:

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

使用Scala的内置模式匹配,我们匹配传入的请求,提取path的第三部分,并获得与该值相对应的用户,甚至应用访问控制检查(当前会话或请求是否有权访问给定的用户logging)。 所以,当User实例碰到应用程序逻辑时,它就被审查了。

凭借这两个核心部分,Lift在安全性方面具有巨大的优势。 为了让你了解Lift的安全性的重要性 ,不妨碍function, Rasmus Lerdorg为Yahoo! 对于FourSquare(电梯海报 – 孩子网站之一)有这样的说法:

四星级的@foursquare – 第一个网站在一段时间,我仔细看了一下,没有一个单一的安全问题(我可以find) – http://twitter.com/rasmus/status/5929904263

当时,FourSquare有一名工程师在做代码(不是@harryh不是一个超级天才),他的主要重点是重写PHP版本的FourSquare,同时应付每周stream量翻倍。

Lift的安全焦点的最后部分是SiteMap。 这是一个统一的访问控制,网站导航和菜单系统。 开发人员使用Scala代码(例如If(User.loggedIn _)If(User.superUser _) )为每个页面定义访问控制规则,并在任何页面呈现开始之前应用这些访问控制规则。 这与Spring Security非常相似,不同之处在于它从项目开始就已经进入了,访问控制规则与应用程序的其他部分是统一的,所以当URL中没有更新XML安全规则的过程时更改或计算访问控制更改的方法。

总结到目前为止,Lift的devise理念为您提供了访问控制的优势,抵御OWASP十大安全漏洞,更好的Ajax支持以及比Spring更高的开发人员生产力。

但是Lift也为您提供了围绕任何Web框架的最佳Comet支持。 这就是为什么NovellselectLift来驱动他们的Pulse产品的原因,以下是Novell关于Lift的说法:

Lift是一种Web框架,可以让您作为开发人员专注于全局。 强大的,富有performance力的打字以及内置的Comet支持等更高级的function使您可以专注于创新而不是pipe道。 构build一个像Novell Pulse这样的丰富的实时Web应用程序需要一个具有Liftfunction的框架。

所以,Lift不仅仅是另外一个MVC框架。 这是一个框架,它有一些核心的devise原则背后已经成熟很好。 这是一个提供安全性和开发人员生产力双重优势的框架。 Lift是一个层层构build的框架,为开发人员提供了基于需求的正确select…视图生成的select,持久性的select等等。

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

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

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

我强烈地研究了使用Lift进行最近的Web项目,而不是Spring MVC的粉丝。 我没有使用最新的版本,但是Spring MVC的早期版本让你跳过了很多的环节来运行一个web应用程序。 我几乎在Lift上销售,直到我看到Lift可以非常依赖于会话,并需要“粘性会话”才能正常工作。 摘自http://exploring.liftweb.net/master/index-9.html#sec:Session-Management

在有标准的会话复制技术之前,您仍然可以使用“粘性会话”将您的应用程序集群化。 所有与HTTP会话有关的请求必须由同一个群集节点处理

所以一旦需要Session,用户将不得不被钉在该节点上。 这就需要智能的负载平衡,并影响缩放,从而阻止Lift成为我的解决scheme。 我最终select了http://www.playframework.org/并且非常高兴。; Play迄今一直稳定可靠,非常容易使用。

没有从Java背景来到Lift和Scala,所以这不是来自个人的经验,但我知道很多Lift开发人员认为Scala是比Java更简洁高效的语言。

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

我讨厌完全抛弃你的世界。 但是你可以在一个应用程序中使用Scala,Java,Lift,Spring,并且不会有问题。

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

让我们考虑你想写一个应用程序。 如果你是一个体面的开发人员,应用程序应该已经build立在你的脑海。 下一步是通过代码发现它是如何工作的。 为了做到这一点,你需要通过一个function将想象的应用程序传递给一个真实世界的应用程序。 该function是一种编程语言。 所以

 Real app = programming language (imagined app) 

所以语言的select很重要。 框架也是如此。 在这里有很多聪明的人会告诉你select什么,但最终,最好的翻译你的想象力的语言/框架应该是你的select。 所以原型与两个,并作出您的select。

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

但主要问题是我们无法比较spring和电梯。 Lift基本上用作UI框架,Spring用作DI框架。
如果你正在开发的Web应用程序,确实有很多的后端,你可以使用电梯。
但如果你的开发Web应用程序有一些系列后端,你definelty需要跳转。