FAQ —— Groovy & Grails

Q: 什么是闭包(Closure)?
A: 我们可以把closure简单地理解为语句块,下面让我们来看一下方法声明和closure定义的相似点:
方法声明:
def sayHello(name) {
    println name
}

sayHello(
" 山风小子 " )

closure定义:
def sayHello  =  { name  ->
    println name
}

sayHello(
" 山风小子 " )

通过代码比较,大家看出相似点了吧。
closure比方法更灵活,可以作为参数传入方法(这点类似于C++中的方法指针),而方法比如本例中的sayHello方法可以通过.&操作符来获得方法闭包
def sayHello(name) {
    println name
}

def sayHelloMethodClosure 
=   this . & sayHello
sayHelloMethodClosure(
" 山风小子 " )

def hello(c) {
    c("Daniel")
}

hello(sayHelloMethodClosure)

所以在Grails中大量的使用clsoure。


Q: ?.是什么

A: ?. 是‘安全引用符’,举例来说:
在Java中,为了程序的鲁棒性(robust),在对一个对象进行操作之前,我们会判断它是否为null
if  ( null   !=  obj) {
  obj.doSomething();
}

而在Groovy就方便多了,您可以用?.来达到上面的目的
obj ? .doSomething()

等价于
obj  ==   null   ?   null  : obj.doSomething()
如果obj为null,则obj?.doSomething()的结果为null,否则就正常执行与Java无异:)

实例:
def obj  =   null
println obj
? .hello()  //  打印出null
由于obj为null,所以就不执行hello(),即便obj中没有定义hello这个方法也不会报错 :)


Q: it是什么?
A: 如果您没有在Groovy的Closure中定义任何变量,那么Groovy会自动帮您定义一个it变量。
举例来说:
//  此处的a为自己定义的变量
def c  =  { a  ->  
    println a
}
c(
" Hello, world " )

注意上下两段代码的区别,下面的Closure没有定义任何变量,当要引用传入的参数时,用it来表示
//  此处的it是Groovy自动帮我们定义的变量
def c  =  {
    println it
}
c(
" Hello, world " )


Q: @Property是什么?
A: 这是以前旧版Groovy的写法,用来定义成员变量,但由于大家反应它太丑了,所以在Groovy1.0+中已不建议使用,请用def替代它。


Q: 如何定制closure的字符串表示?
A: 定制类的字符串表示一般是通过重写(override)toString方法来完成的:
class  A {
    String toString() {
        
" I am A "
    }
}

def a 
=   new  A()
println 
" $a "

但定制closure的字符串表示,则稍微特殊一点,是通过it << "closure的字符串表示",
在Groovy1.1中,"$closure"会将StringWriter的一个实例传给closure的隐式变量it,并引起closure的执行
如果仅仅是closure()的话,并不会有StringWriter实例传给closure的隐式变量it
def c  =  {
    println 
" closure is executed. "
   
// 将这条语句看作toString方法就可以了,注意要使用if (it) {}来判断一下 :)
   
if (it) {
        it  <<   " I am a closure c "
    }
}

println 
" $c "

结果如下所示,闭包c先被执行,然后才执行println打印出closure的字符串表示
closure is executed.
I am a closure c



Q: 出现在闭包中的owner是什么?
A: owner其实就是‘拥有’此闭包的一个对象,举例来说:
class  A {
    def c 
=  {
         println 
" c's owner: $owner "
        
if  (it) {
            it 
<<   " closure c "
        }

        def innerC 
=  {
            println 
" innerC's owner: $owner "
        }
    }

    String toString() {
        
' class A '
    }
}
def a 
=   new  A()
def innerC 
=  a.c()
innerC()
运行结果:
c's owner: class A
c's owner: class A
innerC's owner: closure c


Q: 为什么Grails比Rails更适用于企业应用?(摘自《 对Grails之误解 》)
A: 原因很多,最显著的两个原因就是Spring和Hibernate。到目前为止,有不计其数的组织在采用Spring和HIbernate,他们都有既有的Spring上下文环境,以及已经构造好的Hibernate领域对象等。

在我开始参与Grails项目之前,我就经历过同样的情况。我们设计Grails的目的就是为了让它和这些框架尽可能无缝地整合起来。因此,我们打个比方,你可以把一个用Java编写的Hibernate领域模型及其对应的配置文件直接扔进Grails应用中,然后就可以使用动态的查询方法,并且直接使用GORM了。

此外,Grails控制器使用了标准的Servlet API对象(如request、response和session等),因此可以和其它的Servlet一起使用。毕竟,掀起它的盖头之后,我们会发现它不过是一个Spring MVC应用。另一方面,Rails几乎是按照和EJB2一样的方式设计的(在我发现这点时,怎一个“震惊”二字了得!)。也就是说,你在扩展 ActiveController和ActiveRecord等框架对象时,你也就被绑定在了这套框架上。

在Rails里面根本就不存在领域模型的说法,Rails的模型就是数据库表。这当然是一件好事了,但在企业内部,同一个领域模型可能会在许多不同的应用中服用,比如说桌面应用和Web应用。在Java里,这实际上是非常成熟完善的,通过把类对象及相应映射文件打包成一个JAR文件即可。

Q: 用Grails开发的Web应用如何进行部署?
A: 执行‘grails war’将Web应用打成war包,然后就可以将应用部署到任何符合J2EE规范的Web服务器上了。


To be continued...

相关文章

背景:    8月29日,凌晨4点左右,某服务告警,其中一个...
https://support.smartbear.comeadyapi/docs/soapui/steps/g...
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能...
Scala和Java为静态语言,Groovy为动态语言Scala:函数式编程,...
出处:https://www.jianshu.com/p/ce6f8a1f66f4一、一些内部...
在运行groovy的junit方法时,报了这个错误:java.lang.Excep...