疑惑,spring还玩groovy grailss吗

Grails 技巧 - Grails and Spring
来源:本站原创&
1.在Domain对象中获取Spring applicationContext的方式:
class Book{
def test(){
def applicationContext = domainClass.grailsApplication.mainContext
2.在resources.groovy中 使用Spring SpEL
foo(Foo) {
name = '#{bar.name}'
foo(Foo) {
name = '#{bar.resourceName()}'
3.使用 Property Placeholder
在grails-app/conf/Config.groovy 中配置
database.driver="com.mysql.jdbc.Driver"
database.dbname="mysql:mydb"
在resources.groovy使用上面配置
dataSource(org.springframework.jdbc.datasource.DriverManagerDataSource) {
driverClassName = '${database.driver}'
url = 'jdbc:${database.dbname}'
4.运行时依赖注入
import org.springframework.beans.factory.config.AutowireCapableBeanFactory
def instance = new XXX(...)
def ctx = grailsApplication.mainContext
ctx.beanFactory.autowireBeanProperties(instance,
AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false)
这时候instance 对象的属性跟 Spring 对应同名 bean 关联起来
5.Bean生命周期配置
在resources.groovy中
authenticationManager(com.mycompany.myapp.LdapAuthenticationManager) { bean -&
serverUrl = '...'
password = '...'
bean.initMethod = 'init'
bean.destroyMethod = 'destroy'
或者在实现 InitializingBean、DisposableBean接口
package com.mycompany.myapp
import org.springframework.beans.factory.DisposableBean
import org.springframework.beans.factory.InitializingBean
class LdapAuthenticationManager implements InitializingBean, DisposableBean {
void afterPropertiesSet() {
// initialization work
void destroy() {
// shutdown work
6.Bean 别名
import grails.util.Environment
String realBeanName
switch (Environment.current) {
case Environment.TEST:
realBeanName = 'testCardProcessingService'
case Environment.PRODUCTION:
realBeanName = 'productionCardProcessingService'
default: // Environment.DEVELOPMENT, custom envs
realBeanName = 'mockCardProcessingService'
springConfig.addAlias 'cardProcessingService', realBeanName
7.Resource 依赖注入
package com.mycompany.myapp
import org.springframework.core.io.Resource
class FooManager {
Resource xmlFile
// class methods
import com.mycompany.myapp.FooManager
fooManager(FooManager) {
xmlFile = 'classpath:data.xml'
8.在resources.groovy中使用Spring命名空间
xmlns context:"http://www.springframework.org/schema/context"
context.'component-scan'('base-package': "my.company.domain")
1.在Domain对象中获取Spring applicationContext的方式: class Book{ def test(){ def applicationContext = domainClass.grailsApplication.mainContext } } 2.在resources.groovy中 使用Spring SpEL beans = { bar(Bar) foo(Foo) { name = '#{bar.name}' } } beans = { bar(Bar) fo
1.使用Hibernate XML映射文件 当迁移历史的基于Hibernate的项目到grails,在grails-app/conf/hibernate目录下创hibernate.cfg.xml &?xml version='1.0' encoding='UTF-8'?& &!DOCTYPE hibernate-configuration PUBLIC &-//Hibernate/Hibernate Configuration DTD 3.0//EN& &h
1.Grails 开发的时候要求JDK 6 ,但是可以部署到JDK5环境(BuildConfig.groovy) grails.project.source.level = &1.5& grails.project.target.level = &1.5& 2.指定Servlet 版本(BuildConfig.groovy) grails.servlet.version = &3.0& 3.配置 root logger (Config.groov
1.不生成 version 字段 static mapping = { version false } 2.分页结果集列表 PagedResultList,非常适合分页查询 def c = Account.createCriteria() def results = c.list (max: 50, offset: 10) { like(&holderFirstName&, &Fred%&) and { between(&balance&, 50
1.Default Action Controller 默认Action为 index 可以修改为其它: static defaultAction = &list& 2.Interceptors Before Advice def beforeInterceptor = { log.trace(&Executing action $actionName with params $params&) } After Advice def afterInterceptor
1.view 中内置 grailsApplication 对象,可以用grailsApplication 后取config对象 &html& &body& ${grailsApplication.config} &/body& &/html& 2.使用 tmpl 命名空间 渲染模板 &tmpl:bookTemplate book=&${myBook}& /& 3.使用 pageProperty 获取被装饰页属性 被装饰页例子:
最近,Peter Ledbrook撰写了一篇名为&Spring:Grails的基础&的文章,透过这些文字,我们可以了解Spring和Grails的关系,及其在Grails中发挥的作用. Grails本身也是一个Spring MVC应用,拥有自己的DispatcherServlet.ApplicationContext和相关的Bean,典型的Grails一般都有: grailsApplication – 代表当前应用及其资源的Bean pluginManager – 插件管理器,你可以通过它查询
最近花了些时间了解了一下 Spring Boot 这个新框架.这个框架提供了快速开发基于 Spring Framework 的应用的功能.同样,SpringSource 旗下还有另一个用于 Web 应用快速开发的框架,就是 Grails.初看来这两个框架有很多相似的地方,所以可以将这两个框架做一下对比. Spring Boot 强调自运行:Grails 应用则需要打包成 WAR 来运行 当然 Grails 应用也能通过内嵌的 Tomcat 或 Jetty 容器来运行,但这主要用于开发环境.在用于
i18n mechanism Grails provides a sound i18n mechanism, specific documentation to see if / grails-app/i18n directory will understand. The default will be generated in various languages of the properties file. In many parts of Grails and i18n related.
Jason Lai of the translator Geoffrey Wiseman Posted at half past eight p.m. on July 11, 2007 Community Java Theme Ruby on Rails, JRuby Label Grails Share Share | Grails development team member Marc Palmer published a blog post, for Grails developers
Grails development to master the basic techniques and be able to further independent study of the advanced features of Grails. Grails is built on top of the dynamic language Groovy, an open source MVC Web development framework, Grails is a distinctiv
Grails 网站 : https://grails.org/ Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring.Hibernate和其它标准Java框架之上,从而为大家带来一套能实现超高生产力的一站式框架. Ruby on Rails开创了将一门强大的编程语言和一个坚持己见.提倡用通情达理的默认设置代替复杂配置的框架进行创造性结合的先河.然而,还有许多组织并没有做好 从Java的安全保护伞下走出的准备,也没有打算放弃他们目前在Java上的投入
Feedlr和Grails Feedlr:feed驱动的多平台微博客机器人平台 微博客是由Twitter 创造出的一种web 2.0时代的新事物.在微博客上,人们使用简短的语言随时随地的发表消息,并可以即时地受到好友的消息.由于易用,实时等特点,Twitter在06年推 出至今逐步升温,已经拥有超过300万用户.特别在08年中,Twitter一改起步阶段geek玩具的角色,明显地向主流进化.随着Twitter的兴 起,也出现了非常多其他的微博客.仅国内就有叽歪.饭否.以及做啥等等.微博客的兴起提
Grails的优势 DRY(Don&t Repeat Yourself,不要重复自己),约定优于配置(Convention over Configuration) DRY和约定优先于配置的思想,是由Rails兴起并迅速被广泛接收和欣赏的Web框架新思路.Grails作为JEE世界的Rails,把这些最前沿的设计理念带入已显得陈旧的JEE社区,拥有鲜明突出的特点,以及由此带来的优秀的开发效率. DRY 的思想是避免重复的信息.Grails中的DRY主要提现在URL映射定义上(URLMappings
3月10日,大家翘首以盼的Grails 1.1终于发布了.lucastex决定要对Grails的25个Plugin分别编写手册以帮助大家更好的了解这些插件,手册中将会包括插件的工作方式并提供一些例程,他还邀请大家以投票的方式决定先写其中哪10个插件的相关文档.这也算是对Grails 1.1发布助助威吧. lucastex在其自己的博客上罗列了可选的25个Grails插件,它们分别是: Acegi Security Plugin Avatar Plugin Axis2 Pl
概要 在本次访谈中,来自SpringSource的Graeme Rocher 和 Guillaume Laforge与我们讨论了Grails框架及Groovy语言的现在和将来.Rocher讲述了Grails 1.4[现已更名为2.0,具体信息参见这里]及其增强功能,比如对GORM的改进.Laforge则谈到了Groovy 1.8, 其中包括新的DSL表达能力.他们还谈到了Java未来的变化对他们项目的影响. 个人简介 Graeme Rocher是SpringSource Grails开发部门的负
In advance, I have only a superficial Ruby. And Rails do not come into contact with. After watching the video, or can read, and perhaps what kind of grammar can guess the meaning. Now studying Grails, by Grails so want to see implementation. First an
Before I put the program to upgrade to 1.2 version of Grails, before Jar packages required for the project are on the project in the lib / directory, and I use PostgreSQL as the development database. And now, I have decided to Grails1.2 program the u
Grails will compile to the domain class in the two properties into the id and version (in the compiled class files can be found in them). How it was accomplished? Search Grails source code, the following was found: 1. To find a class called DefaultGr
A few months ago, I have studied the domain class in Grails compile-time properties into feature (see, I argue &Grails domain class to explore the compilation series of attributes into& http://sam-ds-/ blog/676070) In that articl努力其实也是一种天赋。
&原文地址:
grails的思想
1.Don't Repeat Yourself
不要重复你自己
2.Convention over Configuration
约束优于配置
DRY和约定优先于配置的思想,是由Rails兴起并迅速被广泛接收和欣赏的Web框架新思路。Grails作为JEE世界的Rails,把这些最前沿的设计理念带入已显得陈旧的JEE社区,拥有鲜明突出的特点,以及由此带来的优秀的开发效率。
DRY 的思想是避免重复的信息。Grails中的DRY主要提现在URL映射定义上(URLMappings.groovy)。在 URLMappings.groovy中定义了应用的各个URL以后,通过使用Grails预定义的动态Controller方法和GSP标签,开发者就 不必再把程序URL硬编码在各处。比如使用GSP标签, 和,只需要提供Controller,Action和可选的参数,就能产生所需的URL。
在约定优于配置方面,Grails和Rails非常相似。所谓约定优于配置,就是按照框架约定的方式来组织资源,就可以免去任何额外的配置。比如 Grails的自定义标签,存放在应用目录下的grails-app/taglib路径下,并以XXXTagLib.groovy的方式命名,就能无需任 何配置就可以在GSP里使用这些标签库了。另外还有Service类,Job类,包括整个Grails应用的目录结构,都是约定由于配置原则的体现。在这 些方面JEE开发者一定会为摆脱各种繁琐的配置感到异常兴奋,并且实实在在的节约很多开发时间。
通过运行在JVM之上,Grails拥有一个经过多年开发,已经非常成熟,业界标准级别的运行环境。JVM的稳定性和最新版本的性能都已经相当成熟。相比 最直接的比较对象Rails,Grails在运行环境性能上的优势是比较明显的。另外,已有的Java可重用组件基本都可以直接使用于Grails,无疑 也是Grails的一个明显优势。
Groovy语言
Grails和Groovy语言的关系是密不可分的。对于Groovy来说,Grails是其最大的杀手级应用。而对Grails来说,Groovy是其能够实现灵活多变的快速开发,区别于其他运行于JVM之上的Web框架的核心技术。
Groovy的动态特性是其最大亮点,在这方面几乎不输于Ruby等其他热门的动态语言。meta-programming,closure等等热门的动 态语言特性在Groovy中都有很好的实现。而且,Groovy程序能够编译为JVM字节码的.class文件,直接运行在JVM上,Groovy程序的 性能能够得到一定的帮助。Groovy能够和Java混合编写,混合编译,使得Java程序员能不用浪费自己在Java语言上的大量投入,更轻松快捷地进 入Groovy的世界。使用Groovy编程,相比使用Java来说快速轻松得多,对为数众多的Java程序员颇有吸引力。
Grails的插件系统也是其亮点之一。首先,和Rails,Django等Web框架类似,基于微内核的思想,插件(可重用模块)是框架的一等公民。 Grails除了核心模块以外的功能几乎都是通过插件方式实现的。实际上,一个Grails插件和一个Grails应用基本是完全一样的,同样可以使用grails run-app命令来运行。区别仅在于一个插件的根目录下需要提供一个FooPlugin.groovy文件,提供插件的一些描述信息。
Grails插件基本可以做任何事情,Grails社区已经提供了各式各样的插件,发布在Grails官方插件源上。查看现有的官方插件,可以执行下面的命令。
grails list-plugins
在官方源里看到了需要的插件名称(例如foo-plugin),安装插件也只需要一条命令即可。
grails install-plugin foo-plugin
Grails就会下载相应的插件包并解压到本地Grails应用的插件路径下,并自动执行插件自带的安装脚本。
创建自己的插件也同样轻松。首先通过下面的命令自动建立插件项目
grails create-plugin foo
Grails就会自动建立一个插件项目,包括一个FooPlugin.groovy的模板文件。编写Grails插件的具体方法可以阅读。编写好了插件以后,准备发布到官方插件源上的话,首先注册一个codehaus帐号,成为Grails Plugins项目成员,并在官方邮件列表上申请发布权限。然后,只需要一条命令就可以自动发布到官方SVN源,提供给所有人下载了。
grails release-plugin
充分利用好已有的插件,可以进一步加快Grails开发过程。比如我在开发feedlr过程中就使用了Quartz,Searchable,Feeds,OpenID等插件,而且编写并发布了。
GSP和标签库
Grails前端开发使用的是GSP(Grails Server Pages),开发者可以使用Grails特定的模板语法编写gsp动态页面,并且可以直接使用Groovy脚本或是各种预定义和自定义的标签库 (taglib)。这么看起来和JSP区别不大,而实际上,Grails带给开发者的是远比名字上的区别大得多的开发效率上的进步。
首先,虽然不是推荐的做法,但是直接在GSP中使用Groovy脚本的话就直接利用了Groovy快速开发的优势。
另外,JEE开发者对于JSP标签库的易用性大多有所诟病,常常需要做貌似多余的各种配置。而Grails通过DRY和约定优先于配置的思想,使得GSP 标签库的易用性非常棒。框架预定义的标签库自然是什么配置都不需要就可以直接使用了,而利用了Groovy的动态特性的标签语法,可以相当程度地减少编码 量。
编写自定义标签相对于JSP更是异常轻松。只需要通过以下命令新建自定义标签库文件,通过groovy的closure方式编写自定义标签,之后什么配置都不需要,就可以直接在GSP中使用新建的自定义标签了。
grails create-tag-lib
自定义标签库文件存放于应用根路径下的grails-app/taglib目录下,命名规范为XXXTagLib.groovy,通过Grails框架的约定规则就能自动装入了。
成熟的JEE Stack
Grails是一个整合了若干已有JEE组件和框架而成的,其中包括了Spring,Spring Workflow,Hibernate,SiteMesh,JUnit,Ant等。这些都是已经相当成熟的开源组件,是开源JEE Stack的事实规范。通过以这些组件为基础,Grails直接就能在企业应用市场占有一定地位。而社区更是为Grails贡献了不少其他JEE开源组件 的插件。对于企业来讲,Grails直接就是一个很有吸引力的快速原型开发框架,可以直接和广泛使用的已有技术很好的整合。这点可能是Grails和 Rails等类似框架相比,对手短期内无法达到的优势。
软件开发过程没有银弹,Grails也不是圣杯。虽然Grails拥有众多鲜明特点和优势,但目前来看也有不少缺点。
JVM的部署环境
JVM作为Grails的运行环境,是一把双刃剑。在性能出色的同时,JVM对于环境的要求使得Grails应用的部署环境比较有限。由于JVM的特殊 性,时至今日,性价比高的Java服务器依然屈指可数。相对于PHP,Python,甚至Ruby的眼花缭乱的廉价服务器选择,Grails开发者只能眼 红了。这样带来的问题是使用Grails技术的话部署应用的起步成本高,对独立开发者以及对成本敏感的小型创业公司来讲,起步阶段就大多会采用性价比更高 的其他技术。
复合型框架带来的整合复杂性
Grails使用多种已有的成熟开源JEE组件,同样是一把双刃剑。多种组件整合在一起,出现整合方面的问题的话调试修改都会比较吃力。典型的例子是 Grails出错的stack trace,往往会包括了从下层JEE框架抛出的大量异常信息,这些噪音对分析问题造成干扰,对一些疑难问题的解决会造成困难。而且这些底层组件都是传统 的JEE组件,调试起来丝毫无法利用到Groovy和Grails的灵活方便的优点。
开发工具的欠缺
Grails开发使用什么IDE,这是大多开发者接触Grails时最先提出的问题。可惜的是,这个问题至今没有令人信服的答案。在官方邮件列表上,推荐 比较多的是IntelliJ IDEA,其他可选的是Eclipse,Netbeans。IDEA相对来讲对于Groovy/Grails的支持确实做得最全面,但是对于习惯于开源 IDE的大多数JEE开发者来说,切换到另一个陌生的而且购买费用不低的IDE是个不小的代价,而对于企业来讲为此花钱更换开发环境更是个不小的障碍。 Eclipse和Netbeans的Groovy/Grails支持至今还是比较初步和不稳定,而且进展也相当缓慢。目前我个人更倾向于使用Mac TextMate加上Groovy Grails Bundle。但这并不是一个适合所有人的答案。
尚不成熟的社区
这可能是Grails最关键的隐藏的弱点。一个开源项目的成功与否很大程度上取决于其社区。Rails/Ruby,Django/Python,包括 PHP都属于现今最好的开源社区,活跃的社区对开源项目的成长起到巨大的作用。但是Grails的社区至今还是相当小众,在人数和质量上都无法和以上三大 社区相比。一个不成熟的社区带来的一个明显问题就是Grails项目的开发进度比较慢,相关文档和资料缺乏&
敏捷开发框架横向比较:Grails,Rails,Django
和使用Ruby语言的Rails以及使用Python语言的Django相比,使用Groovy语言的Grails可以利用到其整合的JEE组件和JVM本身的性能优势。而在性能是关键的时候,还可以直接使用Java。
Grails项目负责人Graeme Rocher做过一个比较细致的。 在Grails 0.5和Rails 1.2.3的对比测试中,在包括数据CRUD操作在内的所有项目中Grails全面超越Rails,某些项目的优势可以达到40%-50%。不过这个测试 是在07年初做的,目前已经比较过时,两个项目也已经经历了不少更新。但是基本上说,借助了JVM性能优势的Grails相比100%纯Ruby的 Rails还是在微观性能测试中占有一定上风。
由于Ruby默认运行时VM的性能一般,Django采用的Python语言在微性能测试中也要胜于Ruby,但是Grails和Django的直接对比目前似乎还没有详细可靠的资料。
这三种框架在设计理念上基本是一致的:DRY(Don't Repeat Yourself,不要重复自己)和约定优于配置(Convention over Configuration),所以在开发效率上三者基本不相上下。
另外值得一提的是,Groovy语言本身的特点也使其开发效率比Java高出不少,和其他流行动态语言不相上下,对Grails的开发效率功不可没。Grails框架内提供的魔法般的动态方法都是通过Groovy元编程实现的,包括约定优于配置 中Service类的自动注入,builder,codecs等的实现等等。由于篇幅有限此处无法做进一步举例,大家可以从得到详细的资料。
应用的部署可能是这三种框架区别最大的一点。
对于Grails,基本可以部署在任何Java Servlet容器环境下。而在实际情况中,廉价的Java服务器选择很少,一般只能采用VPS或者独立主机的方式部署。而JVM对内存的要求也不低。虽 然有不少在256MB内存的环境下运行Grails的例子,但是要达到实用的性能的话,至少512MB的内存是必须的。比如Feedlr是部署在一台 540MB内存的VPS服务器上(由提供)。
Rails由于其快速窜红,目前可选的部署服务已经不少了。除了VPS和独立主机外,直接支持Rails的廉价共享主机,甚至Rails云计算服务(Heroku)都是不错的选择。
和Rails一样,Django的部署服务选择也不少。从廉价的共享主机到云计算服务,特别值得一提的是支持Django的Google App Engine服务,是一个很有吸引力的选择。
在本系列上文中提到了Grails在开源社区方面的劣势。Grails目前还是一个很年轻的项目,而Groovy也还是一个年轻而小众的语言。在社区方面,Grails的劣势是比较明显的。
Rails 社区是三者中最热闹的。在偶像级人物DHH的带领下,Rails的发展确实让人刮目相看。Django的社区依托了历史悠久而成熟的Python社区,也 发展的相当成熟。成熟的开源社区的一大标志就是有众多高质量的社区代码,包括社区开发的组件和贡献的代码。在这方面Rails和Django都非常典型, 两者目前都已经依托社区建立其了一定规模的核心开发团队。而Grails目前还是主要由G2One团队进行开发,从项目进度来看资源比较紧缺,新版本发布 常被推迟。我在开发Feedlr过程中曾为Grails提交过几个补丁和发布了OAuth插件,在此过程中也感觉Grails还需要更多来自社区的帮助。 在此也希望各位爱好Grails的朋友能多多为Grails贡献代码,一起把社区建设的更好。
Grails的现状和未来
Grails目前主要被少数独立开发者和小型网站采用,另外在使用JEE的大型公司中也有不少使用Grails进行快速原型开发和试验性项目,包括Oracle,SAP等都有使用Grails的例子。
Oracle早在JavaOne 06就宣布支持Grails/Groovy,Oracle官方也给出不少通过Grails使用旗下产品的文档:/search?q=grails%20oracle。
SAP提供了产品,支持使用Grails和Groovy进行SAP产品的开发。
热门的商务SNS网站LinkedIn有使用Grails进行开发的例子,曾经发布过。还曾专门介绍过使用Grails进行内部开发的经验。
更多Grails网站的例子
Grails官方Wiki提供了更多使用Grails搭建的网站的例子:http://grails.org/Success+Stories
总的来说,由于Grails基于JEE的架构,企业市场接受Grails的速度比Rails更胜一筹。但目前Grails还没有较大规模和影响的实际案例,企业采用Grails也尚处于尝试阶段。而Grails部署服务的选择还是不多,但是值得一提的是最近出现的提供的云计算服务,直接支持Grails的部署。相信如果配套的部署服务跟上的话,Grails会得到更多开发者的青睐,并且涌现更多有意思的实际网站案例的。
Groovy和Grails诞生以来一直作为独立的开源社区项目存在,并没有商业支持。在07年9月,Grails和Groovy各自的项目负责人合作成立了公司,专为Grails和Groovy技术提供背后的支持并进行商业化运作。而在08年11月,。这样,以Spring为基础的Grails正式进入了Spring家族,结束了漂流生涯。这对于Grails以及Groovy社区都是一个非常好的消 息。独立开源项目往往受到资金,人力等问题的困扰,而有了商业公司的支持,项目可以拥有全职开发人员,可以有市场推广的预算,并且通过Spring的品牌 和市场占有率,更能提高Grails和Groovy的知名度和业界影响。在09年,随着收购过渡的完成,我们期待Spring给Grails带来的改变, 而带给开发者一个更出色更成熟的开发工具。
Grails是个特色鲜明的Web开发框架。作为一个年轻的开源框架,它有吸引人的特点,但还并不完美。
Grails文档:
Grails插件:
SpringSource收购公告:
Morph Labs:
阅读(...) 评论()8.2 Spring Boot集成Groovy、Grails开发 - 简书
8.2 Spring Boot集成Groovy、Grails开发
8.2 Spring Boot集成Groovy、Grails开发
本章介绍Spring Boot集成Groovy,Grails开发。我们将开发一个极简版的pms(项目管理系统)。
Groovy和Grails简介
Groovy简介
Groovy 是一种动态语言,它在 JVM 上运行,并且与 Java 语言无缝集成。
Groovy 可以大大减少 Java 代码的数量。在 Groovy 中,不再需要为字段编写 getter 和 setter 方法,因为 Groovy 会自动提供它们。不再需要编写 for Iterator i = list.iterator() 来循环遍历一系列的项;list.each 可以做相同的事情,而且看上去更简洁,表达更清晰。简言之,Groovy 就是 21 世纪的 Java 语言。[2]
Groovy 不会替代 Java 语言 — 它只是提供了增强。您可以很快地掌握 Groovy,因为说到底,Groovy 代码就是 Java 代码。这两种语言是如此兼容,甚至可以将一个 .java 文件重命名为一个 .groovy 文件 — 例如,将 Person.java 改为 Person.groovy — 从而得到一个有效的(可执行的)Groovy 文件(虽然这个 Groovy 文件并没有用到 Groovy 提供的任何语法)。
Grails简介
Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring、Hibernate等开源框架之上,是一个高生产力一站式框架。
Grails这个独特的框架被视为是提升工程师生产效率的动态工具,因为其干脆的API设计,合理的默认值以及约定架构。与java的无缝集成使得这个框架成为世界上众多框架中的首选。一系列强大的特性,如基于sping的依赖注入和各式各样的插件,可以提供创建现代基于web的app的所有需要的东西。
我们使用框架。就像 Rails 与 Ruby 编程语言联系非常紧密一样,Grails 也离不开 Groovy。
DRY(Don't Repeat Yourself,不要重复自己)约定优于配置(Convention over Configuration)
DRY和约定优先于配置的思想,是由Rails兴起并迅速被广泛接收和欣赏的Web框架新思路。Grails作为JEE世界的Rails,把这些最前沿的设计理念带入已显得陈旧的JEE社区,拥有鲜明突出的特点,以及由此带来的优秀的开发效率。
对Grails来说,Groovy是其能够实现灵活多变的快速开发,区别于其他运行于JVM之上的Web框架的核心技术。
Groovy的动态特性是其最大亮点,在这方面几乎不输于Ruby等其他热门的动态语言。[3]
Grails实现原理
基于Spring MVC的控制器层
构建于Gant 上的命令行脚本运行环境,内置Tomcat服务器,不用重新启动服务器就可以进行重新加载
基于Spring的MessageSource核心概念,提供了对国际化(i18n)的支持
基于Spring事务抽象概念,实现事务服务层[1]
Github:官网:
数据库的对象关系映射层使用GORM
我们使用 Grail 对象关系映射(Grails Object Relational Mapping,GORM)API 进行数据库层的持久化工作。
安装Grails 3 开发环境
浏览器访问
1.下载并解压 grails.zip。
2.创建一个 GRAILS_HOME 环境变量。
3.将 $GRAILS_HOME/bin 添加到 PATH中。
如果你的电脑上有SDKMAN! (The Software Development Kit Manager),可以直接命令行自动安装Grails最新稳定版本:
$ sdk install grails
安装完毕,验证一下:
$ grails -v
| Grails Version: 3.2.8
| Groovy Version: 2.4.10
| JVM Version: 1.8.0_40
OK, grails开发环境搞定。我们可以看到,grails依赖的Groovy,JVM环境版本。
创建Grails项目
让我们来体验JVM上的Ruby on rails式的命令行自动工程生成的快感吧!
命令行直接运行:
$ grails create-app pms
Resolving dependencies..
| Application created at /Users/jack/book/pms
我们就生成了一个grails工程demo,目录如下:
├── build.gradle
├── gradle
└── wrapper
├── gradle-wrapper.jar
└── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── grails-app
├── assets
├── images
├── apple-touch-icon-retina.png
├── apple-touch-icon.png
├── favicon.ico
├── grails-cupsonly-logo-white.svg
├── skin
├── database_add.png
├── database_delete.png
├── database_edit.png
├── database_save.png
├── database_table.png
├── exclamation.png
├── house.png
├── information.png
├── shadow.jpg
├── sorted_asc.gif
└── sorted_desc.gif
└── spinner.gif
├── javascripts
├── application.js
├── bootstrap.js
└── jquery-2.2.0.min.js
└── stylesheets
├── application.css
├── bootstrap.css
├── errors.css
├── grails.css
├── main.css
└── mobile.css
├── conf
├── application.yml
├── logback.groovy
└── spring
└── resources.groovy
├── controllers
└── pms
└── UrlMappings.groovy
├── domain
├── i18n
├── messages.properties
├── messages_cs_CZ.properties
├── messages_da.properties
├── messages_de.properties
├── messages_es.properties
├── messages_fr.properties
├── messages_it.properties
├── messages_ja.properties
├── messages_nb.properties
├── messages_nl.properties
├── messages_pl.properties
├── messages_pt_BR.properties
├── messages_pt_PT.properties
├── messages_ru.properties
├── messages_sv.properties
├── messages_th.properties
└── messages_zh_CN.properties
├── init
└── pms
├── Application.groovy
└── BootStrap.groovy
├── services
├── taglib
├── utils
└── views
├── error.gsp
├── index.gsp
├── layouts
└── main.gsp
└── notFound.gsp
├── grails-wrapper.jar
├── grailsw
├── grailsw.bat
├── settings.gradle
└── src
├── integration-test
└── groovy
├── main
├── groovy
└── webapp
└── test
└── groovy
29 directories, 62 files
这真的是一键生成。
我们可以直接使用下面的命令运行这个工程:
$ grails run-app
它会自动下载gradle-3.4.1-bin.zip(通常会很慢):
| Resolving Dependencies. Please wait...
Downloading https://services.gradle.org/distributions/gradle-3.4.1-bin.zip
如果我们本地有gradle环境,我们也可将此工程导入idea,配置一下本地的gradle环境。如下图所示:
首次构建,gradle需要下载工程依赖的jar包。
我们可以看到build.gradle里面已经配置好一切:
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.1"
classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}"
version "0.1"
group "pms"
apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"org.grails.grails-gsp"
apply plugin:"asset-pipeline"
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:hibernate5"
compile "org.hibernate:hibernate-core:5.1.3.Final"
compile "org.hibernate:hibernate-ehcache:5.1.3.Final"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.14.1"
runtime "com.h2database:h2"
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
jvmArgs('-Dspring.output.ansi.enabled=always')
addResources = true
minifyJs = true
minifyCss = true
我们在application.yml里面配置一下server.port (默认8080):
port: 8008
命令行执行(我们也可以使用grails run-app运行工程,区别是grails会下载外部gradle包,配置的gradle环境不是本地机器):
gradle bootRun
你将看到类似如下启动日志:
02:18:02: Executing external task 'bootRun'...
:compileJava NO-SOURCE
:compileGroovy UP-TO-DATE
:buildProperties UP-TO-DATE
:processResources
:findMainClass
objc[27257]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/bin/java (0x) and /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x101a4e4e0). One of the two will be used. Which one is undefined.
Grails application running at http://localhost:8008 in environment: development
启动完毕,访问
02.10.49.png
为了演示上的简易性,数据库我们直接用的是H2,在application.yml配置如下:
hibernate:
queries: false
use_second_level_cache: true
use_query_cache: false
region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
environments:
development:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
dbCreate: none
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
建立领域模型Model层
我们继续在当前工程根目录下。使用grails的create-domain-class命令创建领域类:
$grails create-domain-class Project
执行这个命令,grails也会下gradle包。下载完,grails程序自动解压,放到约定的目录,日志如下:
| Resolving Dependencies. Please wait...
Downloading https://services.gradle.org/distributions/gradle-3.4.1-bin.zip
Unzipping /Users/jack/.gradle/wrapper/dists/gradle-3.4.1-bin/71zneekfcxxu7l9p7nr2sc65s/gradle-3.4.1-bin.zip to /Users/jack/.gradle/wrapper/dists/gradle-3.4.1-bin/71zneekfcxxu7l9p7nr2sc65s
Set executable permissions for: /Users/jack/.gradle/wrapper/dists/gradle-3.4.1-bin/71zneekfcxxu7l9p7nr2sc65s/gradle-3.4.1/bin/gradle
Cleaned up directory '/Users/jack/book/pms/build/classes/main'
Cleaned up directory '/Users/jack/book/pms/build/resources/main'
CONFIGURE SUCCESSFUL
Total time: 2 mins 43.589 secs
| Created grails-app/domain/pms/Project.groovy
| Created src/test/groovy/pms/ProjectSpec.groovy
我们继续创建项目Project的里程碑Milestone领域类:
$ grails create-domain-class Milestone
| Created grails-app/domain/pms/Milestone.groovy
| Created src/test/groovy/pms/MilestoneSpec.groovy
我们可以看到这两个类的代码如下:
package pms
class Project {
static constraints = {
package pms
class Milestone {
static constraints = {
一开始,没有什么内容。其中,static constraints变量里面主要定义对应的实体类的约束条件。
下面我们来设计领域对象的属性。
一个项目Project,我们极简化处理,取几个代表的属性,比如:名称,负责人,开始时间,结束时间,状态等。
package pms
class Project {
static constraints = {
Integer id
String name
String owner
Date startDate
Date endDate
String status
通常,一个项目,会有多个里程碑,所以我们这里的里程碑表,多条记录对应一个Project。里程碑属性我们就取: 关联的项目id,名称,负责人,计划时间,实际时间,状态。
package pms
class Milestone {
static constraints = {
Integer id
Integer projectId
String name
String owner
Date expectDate
Date actualDate
String status
使用grails脚手架自动生成Controller层,视图View层代码
grails的脚手架控制值相当简易,简单易用。我们可以使用
grails create-controller $DomainName
: 创建DomainName对应的空Controller
grails generate-controller $DomainName :创建DomainName对应的包含CRUD的Controller
grails generate-all $DomainName: 创建DomainName对应的包含CRUD的Controller,以及对应的视图view模板代码
下面我们就使用grails generate-all来创建Project,Milestone的Controller,以及视图。
$ grails generate-all Project
| Rendered template Controller.groovy to destination grails-app/controllers/pms/ProjectController.groovy
| Rendered template Spec.groovy to destination src/test/groovy/pms/ProjectControllerSpec.groovy
| Scaffolding completed for grails-app/domain/pms/Project.groovy
| Rendered template create.gsp to destination grails-app/views/project/create.gsp
| Rendered template edit.gsp to destination grails-app/views/project/edit.gsp
| Rendered template index.gsp to destination grails-app/views/project/index.gsp
| Rendered template show.gsp to destination grails-app/views/project/show.gsp
| Views generated for grails-app/domain/pms/Project.groovy
$ grails generate-all Milestone
| Rendered template Controller.groovy to destination grails-app/controllers/pms/MilestoneController.groovy
| Rendered template Spec.groovy to destination src/test/groovy/pms/MilestoneControllerSpec.groovy
| Scaffolding completed for grails-app/domain/pms/Milestone.groovy
| Rendered template create.gsp to destination grails-app/views/milestone/create.gsp
| Rendered template edit.gsp to destination grails-app/views/milestone/edit.gsp
| Rendered template index.gsp to destination grails-app/views/milestone/index.gsp
| Rendered template show.gsp to destination grails-app/views/milestone/show.gsp
| Views generated for grails-app/domain/pms/Milestone.groovy
下面是创建之后的工程目录:
我们可以看出,通过统一的约定,我们得到规整的目录结构。很好的体现了“约定优于配置(Convention over Configuration)”的方法论思想。
对控制器的理解可以归结为三个 R:return、redirect 和 render。有些动作利用隐式的 return 语句将数据返回到具有相同名称的 GSP 页面。有些动作进行重定向。
我们看一下ProjectController的index方法:
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Project.list(params), model:[projectCount: Project.count()]
我们没有写list,count,hasErros等方法,GROM都帮我们打理好一切了。具体的实现源码在org.grails.datastore.gorm里面。这个处理方案跟Spring-jpa的思想基本是一样的。都是通过注解元编程,动态生成相应的方法代码。
完成上述步骤,我们就已经有了包含CRUD基本功能的Web应用了,使用
gradle bootRun
命令运行工程,使用浏览器访问:你将看到如下页面:
我们可以看到,“Available Controllers”列表,这个功能模块是通过如下一段gsp代码实现的:
&div id="controllers" role="navigation"&
&h2&Available Controllers:&/h2&
&g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }"&
&li class="controller"&
&g:link controller="${c.logicalPropertyName}"&${c.fullName}&/g:link&
新建一个Project,保存,如下图:
点击Project列表页:
编辑该项目:
Grails通过UrlMappings统一Url映射,简化了Controller到View的映射路径的代码。只要我们按照“约定”的目录结构组织我们的代码即可。
package pms
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
"/"(view:"/index")
"500"(view:'/error')
"404"(view:'/notFound')
Grails框架里面充满了大量“约定规则”,按照“约定规则”编程,我们看到了,代码是如此之“极简”。
我们简单看一个例子。如下图:
这里的“New Milestone”,是怎么实现的呢?我们来看一下milestone/index.gsp里面的一段代码:
&g:message code="default.list.label" args="[entityName]" /&
这里的default.list.label值配置在i18n/messages.properties里面。
default.home.label=Home
default.list.label={0} List
default.add.label=Add {0}
default.new.label=New {0}
default.create.label=Create {0}
default.show.label=Show {0}
default.edit.label=Edit {0}
default.button.create.label=Create
default.button.edit.label=Edit
default.button.update.label=Update
default.button.delete.label=Delete
default.button.delete.confirm.message=Are you sure?
不过,在这种.properties配置文件中,中文可读性比较差。类似这样子:
default.blank.message=[{1}]\u7C7B\uE\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A
gsp代码中,以 g: 为前缀的就是 GroovyTag。
本章pms项目工程源码:
东海陈光剑,号行走江湖一剑客,字之剑。程序员,诗人,作家。
主页: http://universsky.github.io/
博客:https://jason-chen-2017.github.io/Jason-Chen-2017/

我要回帖

更多关于 spring grails 的文章

 

随机推荐