SlideShare una empresa de Scribd logo
1 de 14
Introducing of Grails plugin QIYI AD Team Yan Lei
Plug-in Architecture
Plug-in Structure + grails-app 	+ controllers 	+ domain 	+ taglib etc. + lib + src 	+ java 	+ groovy + web-app 	+ js 	+ css Just like a normal grails application The only difference is the presence of a file 	*GrailsPlugin.groovy The content of the grails-app directory will not be copied into main source tree. Code in src and lib directory will be compiled into main app’s web-app/WEB-INF/classes
Creating Plugin grails create-plugin [PLUGIN NAME] Plugin descriptor example from Quartz Grails plugin class QuartzGrailsPlugin {  defversion = "0.1"  defgrailsVersion = "1.1 > *"  defauthor = "Sergey Nebolsin"  defauthorEmail = "nebolsin@gmail.com"  deftitle = "This plugin adds Quartz job scheduling features to Grails application."  defdescription = ''' …  '''  …  }
Overview of Plugin Closures A plugin can specify multiple closures each of which can manipulate Grails: doWithSpring – Participate in Spring configuration doWithApplicationContext  – Post ApplicationContxtinitialisation activities doWithWebDescriptor  – Modify the XML generated for web.xml at runtime doWithDynamicMethods – Add methods Some Examples
Hooking into Spring Configuration 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.
Hooking into web.xml Generation defdoWithWebDescriptor = { webXml ->  defmappingElement = webXml.'servlet-mapping'  deflastMapping = 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 Initialization Configuration defdoWithApplicationContext = { appCtx->  SessionFactorysf = appCtx.getBean("sessionFactory")  // do something here with session factory  }  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.
Adding Dynamic Methods defdoWithDynamicMethods = { applicationContext-> String.metaClass.swapCase= {->  defsb = new StringBuffer()  delegate.each{  sb<< (Character.isUpperCase(it as char) ?  Character.toLowerCase(it as char) :  Character.toUpperCase(it as char))  }  sb.toString() } assert "UpAndDown" == "uPaNDdOWN".swapCase()  }  In this example we add a new method swapCase to java.lang.String directly by accessing its metaClass.
Reload Events Grails applications must be reloadable during development Plug-ins can define watchedResources that fire onChange event when modified
Example Reloading Plug-in Class I18nGrailsPlugin{ defwatchedResources =  	“file:../grails-app/i18n/*.properties” defonChange = { event -> defmessageSource =   event.ctx.getBean(“messageSource”) messageSource?.clearCache() } } When one changes,event is fired and plugin responds by clearing message cache
The Event Object event.source - The source of the event which is either the reloaded class or a Spring Resource event.ctx- The Spring ApplicationContext instance event.plugin - The plugin object that manages the resource (Usually this) event.application - The GrailsApplication instance
Plugin Load Order Plugin dependencies defdependsOn = [foo: “ * > 1.0”, 			     bar : “ 1.0 > 1.2”] Load Order defloadAfter = [‘controllers’]
Installing & Distributing grails package-plugin Excluded artefacts when Distributing grails-app/conf/DataSource.groovy grails-app/conf/UrlMappings.groovy build.xml Everything within /web-app/WEB-INF grails install-plugin [name] [file path] [url] Specifying plugin location in ‘BuildConfig.groovy’ //useful for modular app where  app & plugin in the same directory Grails.plugin.location.’grails-ui’ = “../grails-grails-ui”

Más contenido relacionado

La actualidad más candente

"13 ways to run web applications on the Internet" Andrii Shumada
"13 ways to run web applications on the Internet" Andrii Shumada"13 ways to run web applications on the Internet" Andrii Shumada
"13 ways to run web applications on the Internet" Andrii ShumadaFwdays
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーTaketoshi 青野健利
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularLoiane Groner
 
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Loiane Groner
 
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...OdessaJS Conf
 
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Loiane Groner
 
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...COMAQA.BY
 
Automated Development Workflow with Gulp
Automated Development Workflow with GulpAutomated Development Workflow with Gulp
Automated Development Workflow with Gulpplewicki
 
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlFull-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlLoiane Groner
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with reactRobert Pearce
 
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Loiane Groner
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS AggregatorShengyou Fan
 
GPerf Using Jesque
GPerf Using JesqueGPerf Using Jesque
GPerf Using Jesquectoestreich
 
Володимир Дубенко "Node.js for desktop development (based on Electron library)"
Володимир Дубенко "Node.js for desktop development (based on Electron library)"Володимир Дубенко "Node.js for desktop development (based on Electron library)"
Володимир Дубенко "Node.js for desktop development (based on Electron library)"Fwdays
 
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurzeFuture Processing
 

La actualidad más candente (20)

Introducing spring
Introducing springIntroducing spring
Introducing spring
 
"13 ways to run web applications on the Internet" Andrii Shumada
"13 ways to run web applications on the Internet" Andrii Shumada"13 ways to run web applications on the Internet" Andrii Shumada
"13 ways to run web applications on the Internet" Andrii Shumada
 
GvaScript Library
GvaScript LibraryGvaScript Library
GvaScript Library
 
V8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパーV8 javascript engine for フロントエンドデベロッパー
V8 javascript engine for フロントエンドデベロッパー
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
 
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
Full-Stack Reactive with Spring WebFlux + Angular - JConf Colombia 2019
 
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...
Олексій Гончар "Використання Electron в розробці корпоративної відео-мессeндж...
 
Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018Angular for Java Enterprise Developers: Oracle Code One 2018
Angular for Java Enterprise Developers: Oracle Code One 2018
 
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...
Дмитрий Лемешко. Comaqa Spring 2018. Continuous mobile automation in build pi...
 
Automated Development Workflow with Gulp
Automated Development Workflow with GulpAutomated Development Workflow with Gulp
Automated Development Workflow with Gulp
 
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java GirlFull-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
Full-Stack Reativo com Spring WebFlux + Angular - Devs Java Girl
 
Gulp: Task Runner
Gulp: Task RunnerGulp: Task Runner
Gulp: Task Runner
 
Static sites with react
Static sites with reactStatic sites with react
Static sites with react
 
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
Full-Stack Reactive with Spring WebFlux + Angular - Oracle Code One 2018
 
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
[Kotlin Serverless 工作坊] 單元 4 - 實作 RSS Aggregator
 
GPerf Using Jesque
GPerf Using JesqueGPerf Using Jesque
GPerf Using Jesque
 
Let's migrate to Swift 3.0
Let's migrate to Swift 3.0Let's migrate to Swift 3.0
Let's migrate to Swift 3.0
 
Володимир Дубенко "Node.js for desktop development (based on Electron library)"
Володимир Дубенко "Node.js for desktop development (based on Electron library)"Володимир Дубенко "Node.js for desktop development (based on Electron library)"
Володимир Дубенко "Node.js for desktop development (based on Electron library)"
 
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze
[Quality Meetup #20] Michał Górski - Continuous Deployment w chmurze
 
非同期javascriptの過去と未来
非同期javascriptの過去と未来非同期javascriptの過去と未来
非同期javascriptの過去と未来
 

Destacado

Groovy Api Tutorial
Groovy Api  TutorialGroovy Api  Tutorial
Groovy Api Tutorialguligala
 
Jayne's media library talk University of Ulster
Jayne's media library talk University of UlsterJayne's media library talk University of Ulster
Jayne's media library talk University of UlsterJayneDunlop
 
Testing Grails Applications With Selenium Rc
Testing Grails Applications With Selenium RcTesting Grails Applications With Selenium Rc
Testing Grails Applications With Selenium RcRobert Fletcher
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionIn a Rocket
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanPost Planner
 

Destacado (7)

Groovy Api Tutorial
Groovy Api  TutorialGroovy Api  Tutorial
Groovy Api Tutorial
 
Jayne's media library talk University of Ulster
Jayne's media library talk University of UlsterJayne's media library talk University of Ulster
Jayne's media library talk University of Ulster
 
Testing Grails Applications With Selenium Rc
Testing Grails Applications With Selenium RcTesting Grails Applications With Selenium Rc
Testing Grails Applications With Selenium Rc
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
 
How to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media PlanHow to Build a Dynamic Social Media Plan
How to Build a Dynamic Social Media Plan
 
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job? Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
 

Similar a Grails Plugin

Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishSven Haiges
 
Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Tugdual Grall
 
Let's play with adf 3.0
Let's play with adf 3.0Let's play with adf 3.0
Let's play with adf 3.0Eugenio Romano
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansCarol McDonald
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to GriffonJames Williams
 
Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StoryKon Soulianidis
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneidermfrancis
 
The Web on OSGi: Here's How
The Web on OSGi: Here's HowThe Web on OSGi: Here's How
The Web on OSGi: Here's Howmrdon
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Jesus Manuel Olivas
 
Griffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java TechnologyGriffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java TechnologyJames Williams
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoasZeid Hassan
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerOrtus Solutions, Corp
 
Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Ortus Solutions, Corp
 
Useful Rails Plugins
Useful Rails PluginsUseful Rails Plugins
Useful Rails Pluginsnavjeet
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Eliran Eliassy
 

Similar a Grails Plugin (20)

Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 EnglishGrails 0.3-SNAPSHOT Presentation WJAX 2006 English
Grails 0.3-SNAPSHOT Presentation WJAX 2006 English
 
Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Scripting Oracle Develop 2007
Scripting Oracle Develop 2007
 
Let's play with adf 3.0
Let's play with adf 3.0Let's play with adf 3.0
Let's play with adf 3.0
 
Agile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with NetbeansAgile web development Groovy Grails with Netbeans
Agile web development Groovy Grails with Netbeans
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Grails 101
Grails 101Grails 101
Grails 101
 
Porting legacy apps to Griffon
Porting legacy apps to GriffonPorting legacy apps to Griffon
Porting legacy apps to Griffon
 
Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle Story
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneider
 
The Web on OSGi: Here's How
The Web on OSGi: Here's HowThe Web on OSGi: Here's How
The Web on OSGi: Here's How
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...
 
Griffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java TechnologyGriffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java Technology
 
Grails Advanced
Grails Advanced Grails Advanced
Grails Advanced
 
GradleFX
GradleFXGradleFX
GradleFX
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and docker
 
Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018
 
Useful Rails Plugins
Useful Rails PluginsUseful Rails Plugins
Useful Rails Plugins
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 

Grails Plugin

  • 1. Introducing of Grails plugin QIYI AD Team Yan Lei
  • 3. Plug-in Structure + grails-app + controllers + domain + taglib etc. + lib + src + java + groovy + web-app + js + css Just like a normal grails application The only difference is the presence of a file *GrailsPlugin.groovy The content of the grails-app directory will not be copied into main source tree. Code in src and lib directory will be compiled into main app’s web-app/WEB-INF/classes
  • 4. Creating Plugin grails create-plugin [PLUGIN NAME] Plugin descriptor example from Quartz Grails plugin class QuartzGrailsPlugin { defversion = "0.1" defgrailsVersion = "1.1 > *" defauthor = "Sergey Nebolsin" defauthorEmail = "nebolsin@gmail.com" deftitle = "This plugin adds Quartz job scheduling features to Grails application." defdescription = ''' … ''' … }
  • 5. Overview of Plugin Closures A plugin can specify multiple closures each of which can manipulate Grails: doWithSpring – Participate in Spring configuration doWithApplicationContext – Post ApplicationContxtinitialisation activities doWithWebDescriptor – Modify the XML generated for web.xml at runtime doWithDynamicMethods – Add methods Some Examples
  • 6. Hooking into Spring Configuration 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.
  • 7. Hooking into web.xml Generation defdoWithWebDescriptor = { webXml -> defmappingElement = webXml.'servlet-mapping' deflastMapping = 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.
  • 8. Doing Post Initialization Configuration defdoWithApplicationContext = { appCtx-> SessionFactorysf = appCtx.getBean("sessionFactory") // do something here with session factory } 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.
  • 9. Adding Dynamic Methods defdoWithDynamicMethods = { applicationContext-> String.metaClass.swapCase= {-> defsb = new StringBuffer() delegate.each{ sb<< (Character.isUpperCase(it as char) ? Character.toLowerCase(it as char) : Character.toUpperCase(it as char)) } sb.toString() } assert "UpAndDown" == "uPaNDdOWN".swapCase() } In this example we add a new method swapCase to java.lang.String directly by accessing its metaClass.
  • 10. Reload Events Grails applications must be reloadable during development Plug-ins can define watchedResources that fire onChange event when modified
  • 11. Example Reloading Plug-in Class I18nGrailsPlugin{ defwatchedResources = “file:../grails-app/i18n/*.properties” defonChange = { event -> defmessageSource = event.ctx.getBean(“messageSource”) messageSource?.clearCache() } } When one changes,event is fired and plugin responds by clearing message cache
  • 12. The Event Object event.source - The source of the event which is either the reloaded class or a Spring Resource event.ctx- The Spring ApplicationContext instance event.plugin - The plugin object that manages the resource (Usually this) event.application - The GrailsApplication instance
  • 13. Plugin Load Order Plugin dependencies defdependsOn = [foo: “ * > 1.0”, bar : “ 1.0 > 1.2”] Load Order defloadAfter = [‘controllers’]
  • 14. Installing & Distributing grails package-plugin Excluded artefacts when Distributing grails-app/conf/DataSource.groovy grails-app/conf/UrlMappings.groovy build.xml Everything within /web-app/WEB-INF grails install-plugin [name] [file path] [url] Specifying plugin location in ‘BuildConfig.groovy’ //useful for modular app where app & plugin in the same directory Grails.plugin.location.’grails-ui’ = “../grails-grails-ui”