译者:
明明如月
审校:
蓝色漂流瓶

经历了多年的发展Java的生态系统逐渐成熟, 这也使得它成为一个最值得信赖的开发平台之一。但特别是对于类似web应用程序它缺乏一个能够快速完成工作的方法。为了避免遭受这类问题困扰,开发人员常常选择其他实现语言及其现代的web框架如Rub和Ruby on Rails、Python Django等。和Java不同的是,这些语言提供一个简单明了的方式来构建web应用程序。
Java Web开发人员:迎来Grails,弥补Java的缺陷。
幸运的是,对于想要构建web应用程序的Java开发人员来说,有一个更好的选择就是使用Grails。在本文中,我们将看到基于Groovy的Grails在JVM领域作为java的替换方案的可行性。我们将看到一些Grails吸引我们Java开发人员或者其他人的例子。
背景故事
在公司工作中我们遇到了这个问题。我们有一个令人痛苦不堪的Spring应用程序。随着应用日益增长的越来越大,我们很快就发现重构和添加功能比想象中的更加麻烦。这一点以及其他的原因,促使我们决定重写我们的核心应用程序。我们也愿意改变或替换现有的技术堆栈。因为Grails是在JVM中运行而且是建立在我们已经熟悉的技术上,因此它看起来像是一个可行的选择。它使用Groovy作为编程语言,但同时允许你和Java代码混用。所以我们开始行动了。
开足马力,全速前进
Grails最擅功能之一就是可以非常容易地创建一个新项目。创建带有用来存放所需要编写的类的所有文件夹的项目结构,只是想运行一行命令这么简单。添加模型类、控制器、服务和web页面也非常轻松。你只需要关心命名规范和将资源放置到正确的位置即可。不像Java那样仅仅因为语法需要而引用不必要的代码。通过使用Grails的两个支柱Spring和Hibernate以及编码习惯等就可以使以上问题得到部分解决。Grails通过绑定Apache Tomcat作为开发服务器来运行项目。你所需要做的只是在我们的IDE中运行项目,服务器就会自动装载我们的代码并发布。Grails的对象关系模型(GORM)和Hibernate一起为我们创建数据库。如果要使用已经存在的数据库,我们需要配置JDBC连接属性或者通过使用默认设置来使用内存实例.一旦带有Grails的服务器启动(比Spring MVC应用启动稍慢),我们还可以编辑代码,还可以通过热部署方法可以使我们的调试会话具有发布的最新版本。通过这种方式唯一不会被重新载入的是实体类。
可以使用SQL脚本来操作数据库,但这常常比较乏味。所有的Grails项目都包含一个引导程序类,当应用运行时,它就会被运行。在这个类中,我们可以存储或者修改数据和初始化,我们的应用状态。这对于我们来说非常实用,所以我们就可以把开发版本中的测试用例移除掉。
在启动引导类中我们不仅可以通过”if”来判断当前运行环境,还可以据此动态修改数据。
数据操作

使用Grails一个比较引人注意的一点是数据操作变得更加容易。从数据库中读取数据是一项必须而且反复做的事情。很多时候读取数据非常简单。比如像获取符合某些条件的一个或多个实体然后将他们封装成一个整体。为什么不用动态查找器呢?它是一种运行时动态创建的查询数据的方法。你所需要做的只是遵循命名规范。
上面这行代码表示获取姓为“Doe”或年龄大于30岁的所有用户。
虽然这并不是一个非常复杂的例子,但你只要理解这个意思就可以了。
如果我没想根据“failedLogins”这个属性值大于10这个条件过滤这个列表该怎么办?如果我们想根据创建时间,对它们进行排序该怎么办?还有如果我们想让他们的姓连接起来或者找到返回用户的最大年龄又该怎么做呢?

上面的例子可能看起来比较简单,但是它向我们展示了Grails在查询、过滤和操作数据方面的强大优势。虽然在Java 8中也可以实现类似的效果, 但是还是要写比Grails更多的代码。
有时候需要一些不同
我们中的大部分人都喜欢在Java中使用一个动态构造器或者带参数的构造器。根据具体情况来选择合适的构造器这点非常好,但是在很多种情况下我们只是为了设置一些属性或者为实例补充属性。Groovy为每一个实体添加了一个特殊的构造器 用一个优雅的map当做参数,通过map来设置属性。
这种方法使得代码更具有表现力,避免了构造器模板代码的臃肿。顺便说一下,这里给出一些比较酷的和优雅的Groovy的maps的例子:

上面的代码演示代码短小、简单而且功能非常强大的例子。它向你展示内部初始化的使用方法和map值如何像对象属性那样操作。对于基本的操作,除非你非要这么做,我们没有必要调用传统的Java方法。
我们需要强大的功能
当然啦,没有框架是万能的。在我们尝试实现自己解决方案之前我们应该看看哪些是已经可用的。为了拓展我们的基于Grails的方法,我们可以使用Grails 插件。安装一个插件,非常容易。只需要在每个Grails项目中都有的BuildConfig类中添加一行即可。

下面的代码添加了 Spring security core到我们的应用中,几乎就不需要再添加额外的配置了。
这和Maven依赖非常像(Maven中也可以引用这个配置类),但是插件因为常包含所有函数而占用空间更大。
话虽然这么说,让我告诉你必须处理的一种情况。我们需要实现一个跨多数聚集的一个搜索。Grails中有一个Elasticsearch插件,用起来非常简单。正如我们上面提到的,我们只需要在配置文件中添加,这个插件的应用就可以了。如果我们想搜索某一个类的实体,我们只需要在这个类中增加一个静态的“searchable” 属性就可以了。如果你愿意,你还可以限制可以作为查询条件的出现。
代码非常少,但是在其内部,Grails和Elasticsearch插件将会自动对所有用户根据name进行索引以方便我们根据name 来查询。实际的搜索调用也非常简洁:

如果你不愿意,我们也不需要接触Lucene索引。所有的功能都会被自动地帮我们做。这个插件甚至还有一个用来控制展示结构的API,可以通过搜索框进行检索。这只是一个例子用来展示使用插件的大量绑定方法帮我们提高编程效率避免自己去实现这类功能。
我们仍然还需要更强大的功能
虽然插件非常好,但是有时候我们并不需要整个插件,我们只是需要其中一部分功能。还是否遇到过你像为现有Java类添加额外的功能却不想覆盖或者拓展他们吗?在Groovy里,你可以为已经存在的内添加方法和属性或者甚至制定他们的实例。例如,当你想格式化日期时你可以为java.util.Date 添加一个formatting 方法而不用去写静态工具类或者定义各种过滤器,这非常酷。
如果你想跟去一个,来对用户列表进行排序,这种情况下该怎么办?(如果在User类中添加一个新的方法,这样代码将会被污染)
你可以为每一个实例添加一个属性。然后根据这个属性进行排序或者是过滤:

Groovy的作者们已经为Java的核心类添加了很多增强的功能,因此我们就不需要那么做了。下面是一些例子。
使用“-”来移除存在于当前集合中的另外一个集合的元素。
还添加了一些计算java.util.Date对象的一些方法。比如需要多次手动做的一些操作,在不将Date转换为Calendar或使用其他库函数的情况下设置或者获取日期的某个属性。
当你想获得数据操作的描述时,可以简单的使用Groovy添加TimeCategory 类即可。

工欲善其事,必先利其器

有很多IDE支持Grails,如基于Eclipse的GGTS和IntelliJ IDEA。它们了解项目的结构可以帮你通过文件夹和资源的方式进行导航,同时也提供常见命令的快捷方式。使用Grails你可以执行命令(来运行项目,或者设置新的插件方法),你需要各种各样的配置,这些都已经包含在IDE中了。Grails web网页模版页面的代码实现非常优雅你常常只是需要引用一个控制器和动作即可。当然了还有很多其他支持Grails的IDE如 Netbeans、TextMate以及Emacs等。
不好的一面是什么?
正如生活中的一切事物一样,Grails也会有一些不足。很多功能都已经被实现了,大部分是一件好事。但是结果有时候并非我们想象的那样。如果不是使用类型(类型在Groovy里面是可选的)和不够小心也会容易出现bug。当你注意到一个错误的时候可能就已经太迟了。写简洁的代码对你同事和你来说非常有吸引力。但是这些看似高效的代码对你同事来说可能并不非常理解。对你自己来说几个月以后可能也会不清楚。这就是我为什么认为Grails比一些传统的框架需要更多的代码规范的原因。
时间就是金钱

其实编写代码不应该花费那么多的时间,这只因为你当前使用的框架需要你花费那么多时间而已。尤其是日益增长的应用需求,我们更应该关注主要的功能,更应该提高高效。时间就是金钱,时间对于市场来说至关重要。你需要在你对手还没有打败你之前快速的行动解决问题。
一些使用Ruby on Rails 或者Python/Django的朋友一直告诉我这些技术多么酷。我花费大量的时间使用Java来写代码和数据库交互并在web页面中展示是多么傻呀。Grails或许真的是一个实用的解决方案。这并不是说你不能用纯的Java、Spring MVC和Hibernate做到。你确实也可以这样做。你的应用可能跑起来能快那么一点。但是如果你使用Grails你的任务将会完成的更快。
译者补充:
Spring Boot 也是一个很好的选择。
其目的是简化新Spring应用的初始搭建以及开发过程。
该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域成为领导者。
英文源:https://www.toptal.com/grails/should-java-developers-give-grails-chance
