Grails provides a number of hooks to leverage the different parts of the system and perform runtime configuration by convention.

Hooking into the Grails Spring configuration

First, you can hook in Grails runtime configuration by providing a property called doWithSpring which is assigned a block of code. For example the following snippet is from one of the core Grails plugins that provides i18n support:

import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

class I18nGrailsPlugin {

def version = 0.1

def doWithSpring = { messageSource(ReloadableResourceBundleMessageSource) { basename = "WEB-INF/grails-app/i18n/messages" } localeChangeInterceptor(LocaleChangeInterceptor) { paramName = "lang" } localeResolver(CookieLocaleResolver) } }

This plugin sets up the Grails messageSource bean and a couple of other beans to manage Locale resolution and switching. It using the Spring Bean Builder syntax to do so.

Participating in web.xml Generation

Grails generates the WEB-INF/web.xml file at load time, and although plugins cannot change this file directly, they can participate in the generation of the file. Essentially a plugin can provide a doWithWebDescriptor property that is assigned a block of code that gets passed the web.xml as a XmlSlurper GPathResult.

Consider the below example from the ControllersPlugin:

def doWithWebDescriptor = { webXml ->
	def mappingElement = webXml.'servlet-mapping'
	def lastMapping = mappingElement[mappingElement.size()-1]
	lastMapping + {
		'servlet-mapping' {
			'servlet-name'("grails")
			'url-pattern'("*.dispatch")
		}
	}
}

Here the plugin goes through gets a reference to the last <servlet-mapping> element and appends Grails' servlet to the end of it using XmlSlurper's ability to programmatically modify XML using closures and blocks.

Doing Post Initialisation Configuration

Sometimes it is useful to be able do some runtime configuration after the Spring ApplicationContext has been built. In this case you can define a doWithApplicationContext closure property.

class SimplePlugin {
     def name="simple"
     def version = 1.1

def doWithApplicationContext = { appCtx -> SessionFactory sf = appCtx.getBean("sessionFactory") // do something here with session factory } }