One of the underlying frameworks of Grails is Spring. A lot of the Grails components are Spring beans and they all live in the Spring application context. Every Grails service we create is also a Spring bean and in this blog post we see how we can inject a Grails service into a Spring bean we have written ourselves.
The following code sample shows a simple Grails service we will inject into a Spring bean:
// File: grails-app/services/com/mrhaki/sample/LanguageService.groovy package com.mrhaki.sample class LanguageService { List<String> languages() { ['Groovy', 'Java', 'Clojure', 'Scala'] } }
We only have one method, languages()
, that returns a list of JVM languages. Next we create a new Groovy class in the src/groovy
directory which will be our Spring bean that will have the LanguageService
injected. We use Spring annotations to make sure our class turns into a Spring bean. With the @Component
we indicate the component as a Spring bean. We use the @Autowired
annotation to inject the Grails service via the constructor:
// File: src/groovy/com/mrhaki/sample/bean/Shorten.groovy package com.mrhaki.sample.bean import com.mrhaki.sample.LanguageService import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @Component class Shorten { private final LanguageService languageService @Autowired Shorten(final LanguageService languageService) { this.languageService = languageService } List<String> firstLetter() { final List<String> languages = languageService.languages() languages.collect { it[0] } } }
The Shorten
class will use the list of JVM languages from the LanguageService
and return the first letter of each language in the firstLetter()
method.
We can instruct Spring to do package scanning and look for Spring beans in for example resources.groovy
, but in Config.groovy
we can also set the property grails.spring.bean.packages
. We define a list of packages for this property and Grails will scan those packages and add any Spring beans to the Spring context. The complete definition in Config.groovy
is now:
... // packages to include in Spring bean scanning grails.spring.bean.packages = ['com.mrhaki.sample.bean'] ...
With the following integration test we can see the Shorten
class is now a Spring bean and we can invoke the firstLetter()
method that uses the Grails service LanguageService
:
// File: test/integration/com/mrhaki/sample/SpringBeanTests.groovy package com.mrhaki.sample import com.mrhaki.sample.bean.Shorten public class SpringBeansTests extends GroovyTestCase { Shorten shorten void testShorten() { assertEquals(['G', 'J', 'C', 'S'], shorten.firstLetter()) } }
Written with Grails 2.2.1