Grails控制器的“expando”方法来自哪里?

时间:2013-09-18 13:09:59

标签: grails

根据documentation,Grails控制器只是一个类,其名称附加了“Controller”并保存在grails-app/controllers/中。这类中最简单的是:

package some.package

class FooController {
  def index = {}
}

运行Grails应用程序时,此控制器将继承一些标准方法,如getParamsgetSession。从附带的屏幕截图中我可以看到这些是通过groovy.lang.ExpandoMetaClass添加的。我没看到的是这是怎么发生的。控制器不实现任何接口或扩展任何抽象。这些方法来自哪里?

Controller object graph

3 个答案:

答案 0 :(得分:5)

从Grails 2.0开始,一种新的方法适用于将动态方法添加到控制器伪像中。您可以逐步访问它们以查看如何将这些属性添加到控制器: -

  • grails中的控制器不是grails-core的一部分,而是一个名为grails-plugin-controllers的grails的插件。
  • 作为插件,相应的*GrailsPlugin类将定义插件的行为。
  • ControllersApi(扩展CommonWebApi)包含要添加到控制器artefact的所有属性。 (从Grails 2.0引入)
  • ControllerGrailsPlugin将ControllersApi注册为spring bean
  • 只需将ControllerApi添加为bean即可。
  • MetaClassEnhancer的概念,它将采用/考虑API(在本例中为ControllerApi),并通过使用反射将CachedMethods添加到人工制品来增强/协调人工制品(控制器)与相应的API,这是#{3}}在grails-core中的作用。
  • BaseApiProvider

现在,在Grails 2.0之前,我们采用了一种不同的方法来将动态属性添加到控制器中。这样,metaClass属性在运行时被添加到控制器,被发现效率较低。每个动态属性都由它自己的类(即:GetParamsDynamicProperty,GetSessionDynamicProperty)表示,它现在还没有使用。

因此,您需要在对象树中查看这些动态方法的内容是magic happens in the Controller plugin class,其中CachedMethods在控制器中可用。希望有所帮助。如果你寻求更多,我会很高兴添加更多。 : - )

答案 1 :(得分:1)

你说得对,Grails'Controllers'在他们从基类继承的意义上并不是真正的控制器,而是它们只是遵循放在grails-app/controllers目录中的惯例的简单POGO。编译应用程序时,通过AST转换将30多种方法混合在一起,其中大多数来自

org.codehaus.groovy.grails.plugins.web.api.ControllersApi,但也来自    org.codehaus.groovy.grails.plugins.converters.api.ConvertersControllersApi,    org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi

前面的内容是由Burt Beckwith从Programming Grails转述的,如果您对Grails的细节感兴趣,我会推荐它。

答案 2 :(得分:0)

引自伯特贝克威思的优秀书籍Programming Grails

  

使用AST将30多种方法混合到控制器类中   转换。大多数是从   org.codehaus.groovy.grails.plugins.web.api.ControllersApi

ControllersApi source