James Sumners
James Sumners

Reputation: 14777

Where do a Grails controller's "expando" methods come from?

According to the documentation, a Grails controller is simply a class with "Controller" appended to the name and saved in grails-app/controllers/. The simplest of such a class being:

package some.package

class FooController {
  def index = {}
}

When the Grails application is run, this controller will inherit some standard methods like getParams and getSession. From the attached screenshot I can see that these are added via groovy.lang.ExpandoMetaClass. What I don't see is how this happens. The controller doesn't implement any interfaces or extend any abstractions. Where do these methods come from?

Controller object graph

Upvotes: 0

Views: 357

Answers (3)

dspies
dspies

Reputation: 1543

You are right, Grails 'Controllers' are not really Controllers in the sense they inherit from a base class, but rather they are just simple POGOs that follow the convention of being placed in the grails-app/controllers directory. When your application is compiled, 30+ methods are mixed in through AST transformations, the majority of them coming from

org.codehaus.groovy.grails.plugins.web.api.ControllersApi, but also from org.codehaus.groovy.grails.plugins.converters.api.ConvertersControllersApi, org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi.

The preceding was paraphrased from Programming Grails by Burt Beckwith, and I would recommend it if you are interested in the finer details of Grails.

Upvotes: 1

dmahapatro
dmahapatro

Reputation: 50245

From Grails 2.0 a new methodology was adapted to add the dynamic methods to the controller artefacts. You can visit them step wise to see how those properties are added to Controllers:-

  • Controller in grails is not part of grails-core but a plugin by itself to grails named grails-plugin-controllers.
  • Being a plugin, the corresponding *GrailsPlugin Class would define the behavior of the plugin.
  • ControllersApi (extending CommonWebApi) bears all those properties which are to added to controller artefact. (Introduced from Grails 2.0)
  • ControllerGrailsPlugin registers ControllersApi as a spring bean.
  • There is more to just adding ControllerApi as a bean.
  • There is a concept of MetaClassEnhancer which would take/consider an API (in this case ControllerApi) and enhance/reconcile the artefact (controller) with the corresponding API by adding CachedMethods to the artefact using reflection, which is the role of a BaseApiProvider present in grails-core.
  • This magic happens in the Controller plugin class as well.

Now, prior to Grails 2.0 a different method was adapted to add the dynamic properties to controller. That way metaClass properties were added to controllers at runtime which was found to be less efficient. Each of the dynamic property was represented by its own class (viz: GetParamsDynamicProperty, GetSessionDynamicProperty) which is not in use right now.

So what you need to look now in the object tree for those dynamic methods is this where the CachedMethods are available in the controller. Hope that helps. I would be glad to add more if you seek more. :-)

Upvotes: 5

Andrew
Andrew

Reputation: 2249

Quoting from Burt Beckwith's excellent book, Programming Grails:

Over 30 methods are mixed into controller classes with AST transformations. The majority are added from the org.codehaus.groovy.grails.plugins.web.api.ControllersApi class

ControllersApi source

Upvotes: 0

Related Questions