Grails and Spring

Injecting Grails Services into Spring Beans

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())
    }

}

Code written with Grails 2.2.1

Original blog post written on February 27, 2013.

Conditionally Load Bean Definitions from resources.groovy

We can define new bean definitions in several ways with Grails. One of them is via the resources.groovy file in the directory grails-app/conf/spring . This file is parsed and bean definitions are added to the Spring application context. The good thing is we can add Groovy code to this file to conditionally load bean definitions.

First we specify different bean definitions for different environments. Grails already has a development, test and production environment, but we can also use a custom environment. In the following sample we set the property of the Sample bean based on the environment the application is running in. We use the method Environment.executeForEnviroment() where we can use a DSL to indicate the name of the environment and the code we want to execute for that environment. First the code for the Sample class:

// File: src/groovy/com/mrhaki/grails/Sample.groovy
package com.mrhaki.grails

class Sample {
    String environment
}

Next we change the resources.groovy file and set the property environment to a different value for each environment:

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.grails.Sample
import grails.util.Environment

beans = {
    // Define bean with default value for property environment.
    // Bean definition is overridden in
    // Environment.executeForCurrentEnvironment block.
    sample(Sample) {
        environment = 'default'
    }

    Environment.executeForCurrentEnvironment {
        // Override bean definition in 'development' mode.
        development {
            sample(Sample) {
                environment = 'Development'
            }
        }

        // Override bean definition for custom environment 'mrhaki'.
        // Start grails with -Dgrails.env=mrhaki to enable this environment.
        mrhaki {
            sample(Sample) {
                environment = 'Custom mrhaki'
            }
        }

    }
}

We can also use configuration properties to conditionally load bean definitions. In our resources.groovy the grailsApplication object is automatically injected. We can use this variable and get to the configuration properties. So we can define a configuration property in our grails-app/conf/Config.groovy file and use the value in resources.groovy in a condition to load a bean definition.

Let’s add a new boolean property to our configuration sample.load and use it in our resources.groovy:

// File: grails-app/conf/Config.groovy
...
sample.load = true
...
// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.grails.Sample

beans = {
    // Define bean with default value for property environment.
    // Bean definition is overridden in
    // Environment.executeForCurrentEnvironment block.
    sample(Sample) {
        environment = 'default'
    }

    if (grailsApplication.config.sample.load) {
        sample(Sample) {
            environment = 'Set by configuration'
        }
    }
}

We could have achieved the same thing in this samples with changing bean properties via configuration, because in the sample we only change the property value. But we can do much more than simply change property values and for example load extra beans conditionally based on the Grails environment or a configuration property, which we cannot do with just changing properties via configuration.

Code written with Grails 2.2.1

Original blog post written on March 05, 2013.

Using Spring Bean Aliases

Grails uses dependency injection by convention. This means if we have a property messageService then a Spring bean or Grails service with the name messageService is injected. Grails will automatically use the name of a Grails service as the name of the Spring bean definition (applying Java Bean conventions and start with a lowercase). So if we have a Grails service MessageService the resulting Spring bean definition will have the name messageService. Any Spring bean that wants to use the service only has to create the property messageService and dependency injection by convention makes sure the Grails service is injected.

We can change the Spring bean definition name using Spring bean aliases. With an alias we provide an extra name for a Spring bean. In our Grails application we can add an alias in the resources.groovy file in the directory grails-app/conf/spring. In the following sample we add the alias message for the MessageService Grails service:

// File: grails-app/conf/spring/resources.groovy
beans = {
    springConfig.addAlias 'message', 'messageService'
}

We can use aliases to provide different service implementations and conditionally (for example based on environment) activate an implementation. The class that wants to use the service only has to use the dependency injection by convention and define a property with a name. In the resources.groovy file we can then set the alias with the correct name to the implementation we need.

Let’s see how this works with an example. Suppose we have a controller that depends on a service with the name messageService. We use an interface to define the type of the service in our sample, but that is not necessary, we could do the same thing without interfaces:

//File: grails-app/controllers/com/mrhaki/grails/spring/MessageController.groovy
package com.mrhaki.grails.spring

class MessageController {

    MessageService messageService

    def index() {
        render messageService.message
    }
}

Let’s create the interface, which is very simple in our sample:

// File: src/groovy/com/mrhaki/grails/spring/MessageService.groovy
package com.mrhaki.grails.spring

interface MessageService {

    String getMessage()

}

Next we create two Grails services that implement the MessageService interface: MessageRemoteService and MessageLocalService:

// File: grails-app/services/com/mrhaki/grails/spring/MessageRemoteService.groovy
package com.mrhaki.grails.spring

class MessageRemoteService implements MessageService {

    String getMessage() {
        'Remote message'
    }

}
// File: grails-app/services/com/mrhaki/grails/spring/MessageLocalService.groovy
package com.mrhaki.grails.spring

class MessageLocalService implements MessageService {

    String getMessage() {
        'Local message'
    }

}

If we run the Grails application we don’t have a Spring bean definition with the name messageService, but we do have two bean definitions with the names messageRemoteService and messageLocalService. To make sure the MessageController will have the correct service injected we need to add aliases to resources.groovy. By default we want to use the messageRemoteService as messageService, but during development we want to use messageLocalService:

// File: grails-app/conf/spring/resources.groovy
import grails.util.Environment

beans = {
    // Default we use the messageRemoteService as implementation of MessageService
    springConfig.addAlias 'messageService', 'messageRemoteService'

    Environment.executeForCurrentEnvironment {
        development {
            // In development we use messageLocalService as implementation
            // of MessageService.
            springConfig.addAlias 'messageService', 'messageLocalService'
        }
    }
}

So with aliases it is easy to swap service implementations, based on some condition. This can be very useful if we have a service and want to use a mocked or simplified version during development and test for example. This post is based on the presentation Under the hood: Using Spring in Grails and blog post by Burt Beckwith

Code written with Grails 2.2.1

Original blog post written on March 06, 2013.

Use Constructor Argument Based Dependency Injection

We can define extra Spring beans for our Grails application in grails-app/conf/spring/resources.groovy using a DSL. For example we want to use third-party classes as Spring components. Then we can define the bean in resources.groovy and use dependency injection to use it in Grails controllers, services or other classes. If the class is defined so dependencies need to be injected via constructor arguments we must use a special DSL syntax. Normally we define a bean using the following syntax: beanName(BeanClass). To pass constructor arguments we must add those as method arguments after BeanClass. For example if the constructor has a single argument of type String we can use the following syntax: beanName(BeanClass, '42')

We have an alternative way and that is via a closure we can use for the bean definition. The closure will have one argument which is a BeanDefinition object. The BeanDefinition object has a constructorArgs property that takes a list of constructor arguments. So our previous example would become: beanName(BeanClass) { it.constructorArgs = ['42'] }.

Let’s see how this works with an example. First we create a simple Grails service, this service will be injected into a Groovy class we will configure via constructor arguments.

// File: grails-app/services/com/mrhaki/grails/spring/LanguageService.groovy
package com.mrhaki.grails.spring

class LanguageService {

    List<String> findAllLanguages() {
        ['Groovy', 'Java', 'Scala', 'Clojure']
    }

}

Next we create a Groovy class LanguageProvider. This class will use the Grails service and a search pattern to find a language, but those are set via the constructor arguments:

// File: src/groovy/com/mrhaki/grails/spring/LanguageProvider.groovy
package com.mrhaki.spring

class LanguageProvider {

    final def languageService
    final String searchPattern

    LanguageProvider(final def languageService, final String searchPattern) {
        this.languageService = languageService
        this.searchPattern = searchPattern
    }

    List<String> getGr8Languages() {
        final List<String> languages = languageService.findAllLanguages()
        final List<String> gr8Languages = languages.findAll { it =~ searchPattern }
        gr8Languages
    }
}

To configure the LanguageProvider class as Spring bean we add the bean definition to resources.groovy:

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.spring.LanguageProvider

beans = {

    // Pass constructor arguments: ref('languageService') and '^Gr.*'
    // to LanguageProvider.
    languageProvider(LanguageProvider, ref('languageService'), '^Gr.*')

}

Or we can use the BeanDefinition that is passed to the closure:

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.spring.LanguageProvider

beans = {

    languageProvider(LanguageProvider) { beanDefinition ->
        // Pass constructor arguments: ref('languageService') and '^Gr.*'
        // to LanguageProvider.
        beanDefinition.constructorArgs = [ref('languageService'), '^Gr.*']
    }
}

Grails 2.2.1 is used to write this blog post.

Original blog post written on March 10, 2013.

Set Property Values of Spring Beans in resources.groovy

We can configure Spring beans using several methods in Grails. We can for example add them to resources.xml in the directory grails-app/conf/spring using Spring’s XML syntax. But we can also use a more Groovy way with resources.groovy in the directory grails-app/conf/spring. We can use a DSL to define or configure Spring beans that we want to use in our Grails application. Grails uses BeanBuilder to parse the DSL and populate the Spring application context.

To define a bean we use the following syntax beanName(BeanClass). If we want to set a property value for the bean we use a closure and in the closure we set the property values. Let’s first create a simple class we want to configure in the Spring application context:

// File: src/groovy/com/mrhaki/spring/Person.groovy
package com.mrhaki.spring

import groovy.transform.ToString

@ToString
class Person {
    String name
    Date birthDate
}

Next we configure the bean in resources.groovy:

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.spring.Person

beans = {

    mrhaki(Person) {
        name = 'mrhaki'
        birthDate = Date.parse('yyyy-MM-dd', '1973-7-9')
    }

}

There is also an alternative syntax using Groovy’s support for named method arguments. In Groovy named arguments are all grouped into a Map object and passed as the first argument. The BeanBuilder DSL supports this feature. When we define a bean we can use named arguments for the property names and values, use the BeanClass argument and automatically this will be converted to Map and BeanClass type arguments.

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.spring.Person

beans = {

    // Using named arguments to set property values. The named arguments
    // can be grouped together, but don't have to. Groovy will automatically
    // group them together into a Map and makes it the first argument of
    // the 'mrhaki() bean definition method'.
    mrhaki(name: 'mrhaki', Person, birthDate: Date.parse('yyyy-MM-dd', '1973-7-9'))

}

Written with Grails 2.2.1

Original blog post written on March 12, 2013.

Setting Property Values through Configuration

In Grails we can define properties for services, controller, taglibs, Spring components and other components in the Spring application context through configuration. This is called property overriding in Spring terminology. This feature is very useful to define or override property values on components in the application context. We can define the property values in a beans{} block in Config.groovy. We can also load external configuration files, like property files and define property values in those.

With property overriding we don’t have to look for property values via an injected GrailsApplication object and the config property of GrailsApplication. The code using the property value is now much cleaner and easier to test.

In the following sample configuration we override a message property value for the SampleService, the controller SampleController, tag library SampleTagLib and a Spring component MessageProvider:

// File: grails-app/conf/spring/resources.groovy
import com.mrhaki.grails.conf.*

import com.mrhaki.grails.conf.SampleTagLib as STL

...
beans {
    // Grails service.
    sampleService {
        message = 'Value for com.mrhaki.grails.conf.SampleService'
    }

    // A controller class is defined as Spring bean with
    // the name of the class including the package.
    "${SampleController.canonicalName}" {
        message = 'Value for com.mrhaki.grails.conf.SampleController'
    }

    // A tag library class is defined as Spring component where
    // the name is the class name including the package.
    "${STL.canonicalName}" {
        message = 'Value for com.mrhaki.grails.conf.SampleTagLib'
    }

    // Spring bean. Can be configured for example in
    // grails-app/conf/resources.groovy as:
    // beans = {
    //     messageProvider(com.mrhaki.grails.conf.MessageProvider)
    // }
    messageProvider {
        message = 'Value for com.mrhaki.grails.conf.MessageProvider'
    }
...

The information can also be included in an externalized configuration file. In the following Config.groovy we load the the file beans-config.properties to set the value of the message property.

// File: grails-app/conf/Config.groovy
...
grails.config.locations = ['classpath:beans-config.properties']
...

The property file has the following content:

# File: src/java/beans-config.properties
beans.sampleService.message = Value for com.mrhaki.grails.conf.SampleService
beans.com.mrhaki.grails.conf.SampleController.message = Value for com.mrhaki.grails.conf.SampleControl\
ler
beans.com.mrhaki.grails.conf.SampleTagLib.message = Value for com.mrhaki.grails.conf.SampleTagLib
beans.messageProvider.message = Value for com.mrhaki.grails.conf.MessageProvider

The following code sample shows the implementation of the Grails service SampleService to see how we define the property and use the value defined in the configuration:

// File: grails-app/service/com/mrhaki/grails/conf/SampleService.groovy
package com.mrhaki.grails.conf

class SampleService {

    String message

    String tell() {
        "I want to tell you $message"
    }
}

Code written with Grails 2.2.4

Original blog post written on October 07, 2013.

Defining Spring Beans With doWithSpring Method

Grails 3 introduces GrailsAutoConfiguration as the base class for a Grails application. We can extend this class, add a main method and we are ready to go. By default this class is the Application class in the grails-app/init directory. We can override several Grails lifecycle methods from the GrailsAutoConfiguration base class. One of them is doWithSpring. This method must return a closure that can be used by the Grails BeanBuilder class to add Spring beans to the application context. The closure has the same syntax as what we already know for the grails-app/conf/spring/resources.groovy file, we know from previous Grails versions.

We start with a simple class we want to use as a Spring bean:

// File: src/main/groovy/com/mrhaki/grails/SampleBean.groovy
package com.mrhaki.grails

class SampleBean {
    String message
}

Next we create a class that implements the CommandLineRunner interface. Grails will pick up this class, if we configure it as a Spring bean, at startup and executes the code in the run method.

// File: src/main/groovy/com/mrhaki/grails/SamplePrinter.groovy
package com.mrhaki.grails

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.CommandLineRunner

class SamplePrinter implements CommandLineRunner {

    @Autowired
    SampleBean sample

    @Override
    void run(final String... args) throws Exception {
        println "Sample printer says: ${sample.message}"
    }
}

Now we are ready to register these classes as Spring beans using the doWithSpring method in our Application class:

// File: grails-app/init/com/mrhaki/grails/Application.groovy
package com.mrhaki.grails

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration

class Application extends GrailsAutoConfiguration {

    @Override
    Closure doWithSpring() {
        // Define closure with Spring bean
        // definitions, like resources.groovy.
        def beans = {
            // Define Spring bean with name sample
            // of type SampleBean.
            sample(SampleBean) {
                message = 'Grails 3 is so gr8!'
            }

            // Register CommandLineRunner implementation
            // as Spring bean.
            sampleBootstrap(SamplePrinter)
        }
        return beans
    }

    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }

}

Now we can run our Grails application and in our console we see the message:

grails> run-app
| Running application...
Sample printer says: Grails 3 is so gr8!
Grails application running at http://localhost:8080 in environment: development
grails>

Written with Grails 3.0.7.

Original blog post written on September 22, 2015.

Use Spring Java Configuration

A Grails application uses Spring under the hood, which means we can also use all of Spring’s features in a Grails application. For example we can use the Spring Java configuration feature with our Grails application. The Java configuration feature allows us to write a Java or Groovy class to define beans for our application. Of course in Grails we have the nice bean builder syntax when we define beans in the grails-app/conf/spring/resources.groovy file, but maybe we must include a Java configuration from an external library or we just want to write a configuration class ourselves.

This post is very much inspired by this blog post by Andres Steingress.

First we create a simple Groovy class that we want to be instantiated via our Java configuration class:

// File: src/groovy/com/mrhaki/grails/Sample.groovy
package com.mrhaki.grails

class Sample {

    final String name

    Sample(final String name) {
        this.name = name
    }

}

Next we create a new Groovy class and apply the @Configuration annotation so Spring knows this is a class that is used to define beans. Inside the class we define public methods annotated with the @Bean annotation. By default the name of the method is also the name of the bean in the application context. We can specify a different name as an attribute of the @Bean annotation. We can inject other beans into our configuration class, for example GrailsApplication to access the configuration of our application.

// File: src/groovy/com/mrhaki/grails/BeansConfiguration.groovy
package com.mrhaki.grails

import org.codehaus.groovy.grails.commons.GrailsApplication
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class BeansConfiguration {

    // We can inject other Spring beans in our
    // configuration class. By default wiring
    // is done by type, so if we specify a type
    // it works.
    @Autowired
    GrailsApplication grailsApplication

    // If we want to wire by name we can use the
    // @Qualifier annotation:
    // @Autowired
    // @Qualifier('grailsApplication')
    // def grailsApplication

    @Bean
    Sample sample() {
        new Sample(grailsApplication.config.app.sample)
    }

}

The last step is to make sure our configuration class is picked up by Spring so the sample bean is configured. We use the Grails configuration property grails.spring.bean.packages to indicate the package our configuration class is in. When Grails starts all classes in the package and sub-packages are scanned to see if they are Spring components.

// File: grails-app/conf/Config.groovy
...
// packages to include in Spring bean scanning
grails.spring.bean.packages = ['com.mrhaki.grails']
...
// Set sample configuration property,
// which is used in BeansConfiguration.
app.sample = 'Grails is gr8!'
...

Code written with Grails 2.4.2.

Original blog post written on August 05, 2014.

Conditionally Load Beans in Java Configuration Based on Grails Environment

In a previous post we saw that we can use Spring’s Java configuration feature to load beans in our Grails application. We can use the @Profile annotation to conditionally load beans based on the currently active Spring profile. We can for example use the Java system property spring.profiles.active when we start the Grails application to make a profile active. But wouldn’t it be nice if we could use the Grails environment setting to conditionally load beans from a Java configuration? As it turns out Grails already set the current Grails environment name as the active profile for the Grails application. So we can simply use @Profile in our configuration or component classes, like in a non-Grails Spring application.

We can use the @Profile annotation in a Spring Java configuration class. The following sample shows different values for the @Profile annotation. The annotation is applied to methods in the sample code, but can also be applied to a class.

// File: src/groovy/com/mrhaki/grails/configuration/BeansConfiguration.groovy
package com.mrhaki.grails.configuration

import org.springframework.context.annotation.*

@Configuration
class BeansConfiguration {

    // Load for Grails environments
    // development or test
    @Bean
    @Profile(['development', 'test'])
    Sample sampleBean() {
        new Sample('sampleBean')
    }

    // Load for every Grails environment NOT
    // being production.
    @Bean
    @Profile('!production')
    Sample sample() {
        new Sample('sample')
    }

    // Load for custom environment name qa.
    @Bean
    @Profile('qa')
    Sample sampleQA() {
        new Sample('QA')
    }

}

We can also use the annotation for classes that are annotated with the @Component annotation:

// File: src/groovy/com/mrhaki/grails/Person.groovy
package com.mrhaki.grails

import org.springframework.stereotype.Component
import org.springframework.context.annotation.Profile

@Component
@Profile('development')
class Person {
    String name
    String email
}

Code written with Grails 2.4.2.

Original blog post written on August 05, 2014.

Don’t Invalidate Session After Logout with Spring Security Plugin

The Spring security plugin makes it easy to add authentication and autorization to our Grails application. The underlying Spring security framework is still accessible using Spring configuration and as a matter of fact the plugin uses a lot of the Spring security components. When we choose the logout action so-called logout handlers are configured and we can customize them in the Spring configuration of our Grails application.

One of the logout handlers is a Spring bean with the name securityContextLogoutHandler of type org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler. This handler will clear the security context and invalidate a HTTP session if it is available. If we don’t want to invalidate the session we must reconfigure this Spring bean. The good thing is we can override bean definitions in our Grails application. For example we can define a bean in grails-app/conf/spring/resources.groovy with the same name securityContextLogoutHandler and type, but use different property values. In our sample we must set the property invalidateHttpSession of org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler to false. Now our session is not invalidated, but the security context is still cleared.

// File: grails-app/conf/spring/resources.groovy
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler

beans = {
    securityContextLogoutHandler(SecurityContextLogoutHandler) {
        invalidateHttpSession = false
    }
}

Sample written with Grails 2.2.1 and Spring security core plugin 1.2.7.3

Original blog post written on March 11, 2013.