May 23, 2013

Accessing Grails Configuration with Spring Property Placeholders

It seems like everybody approaches the issue of accessing their configuration from their application code in a different way. Grails gives us some helpful shortcuts that make accessing the configuration pretty easy. Simply injecting the <a href="http://grails.org/doc/latest/api/org/codehaus/groovy/grails/commons/GrailsApplication.html">grailsApplication</a> bean in any of your controllers or services will let you access the magical <a href="http://grails.org/doc/latest/api/org/codehaus/groovy/grails/commons/GrailsApplication.html#getConfig()">config</a> property. From there, all global and environment-specific configurations are available as attributes of the <a href="http://groovy.codehaus.org/gapi/groovy/util/ConfigObject.html">ConfigObject</a> instance, and can be accessed with JavaBean-style ‘dot’ notation.

A common approach that I’ve seen in Grails applications is to create a ConfigurationService with helper methods for accessing the config. You can think of this approach as a shortcut, but it probably adds a layer of unnecessary abstraction when you want to be more explicit. It also means having another service to maintain, when you really just need a variable representing a configuration value.

Luckily, Grails is a fully loaded Spring application and the framework developers have gone to great lengths to ensure that the Grails abstraction integrates seamlessly within the Spring application context. To that end, we can realize that the Grails configuration is exposed to the Spring <a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/core/env/Environment.html">Environment</a> and the directives therein are able to be accessed with property placeholder expressions throughout the application.

Now, in your services and controllers you can explicitly wire properties for the configuration directive that you need by using Spring’s <a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/beans/factory/annotation/Value.html">@Value</a> annotation. Consider the following configuration and service that demonstrates using Spring’s constructs to assign configuration values to variables within a service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.objectpartners.application.config
 
config {
social {
twitter {
consumerKey = "ABCD"
consumerSecret = "EFGH"
accessToken = "IJKL"
accessTokenSecret = "MNOP"
}
faceboook {
...
}
linkedin {
...
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TwitterService {
@Value('${config.social.twitter.consumerKey}')
private String consumerKey
 
@Value('${config.social.twitter.consumerSecret}')
private String consumerSecret
 
@Value('${config.social.twitter.accessToken}')
private String accessToken
 
@Value('${config.social.twitter.accessTokenSecret}')
private String accessTokenSecret
 
TwitterTemplate createTwitterTemplate() {
new TwitterTemplate(consumerKey, consumerSecret, accessToken, accessTokenSecret)
}
}

 
It’s important to note the single quotes in the annotation value field. This is necessary due to Groovy and the Spring Expression Language (SpEL) sharing the same notation for evaluating expressions. In this case, we don’t want Groovy to try to interpret this as an expression, as it will only make sense to the SpEL parser.

About the Author

Object Partners profile.

One thought on “Accessing Grails Configuration with Spring Property Placeholders

  1. Gary says:

    What about domain classes?

  2. Dan Woods says:

    Yes, because all domain classes are autowire candidates, but not in the conventional way of using domain classes. By that, I mean that typically when creating a new domain object, you would use the “new DomainClass()” syntax. This is great, but it bypasses the Spring context when getting the new object…

    Luckily, Grails domain classes are prototype scoped, so by resolving the new instance of the domain class through the Spring context, you can have the placeholder properties populated.

    Example: https://gist.github.com/danveloper/9e6aabca51afe68cd0c8

  3. DB says:

    What about unit testing? How will these values be resolved, and how do you mock them?

    1. Dan Woods says:

      Good question…

      The short answer is that you’re going to have some difficulty resolving property placeholders in a Grails unit test. The reason for that is that the unit test environment is a really, really stripped down application context, which doesn’t include things like property placeholder configurators.

      In integration tests you have a full spring context, so property placeholders are useable. You can use Grails’ environment-scoped properties to override them for the “test” environment. See https://gist.github.com/danveloper/8bebd2e55ed8bcf60e39 for more details on that.

      If you *must* test some domain logic in a domain class in a unit test, then it’s probably suitable to just assign the property directly.

Leave a Reply

Your email address will not be published.

Related Blog Posts
Natively Compiled Java on Google App Engine
Google App Engine is a platform-as-a-service product that is marketed as a way to get your applications into the cloud without necessarily knowing all of the infrastructure bits and pieces to do so. Google App […]
Building Better Data Visualization Experiences: Part 2 of 2
If you don't have a Ph.D. in data science, the raw data might be difficult to comprehend. This is where data visualization comes in.
Unleashing Feature Flags onto Kafka Consumers
Feature flags are a tool to strategically enable or disable functionality at runtime. They are often used to drive different user experiences but can also be useful in real-time data systems. In this post, we’ll […]
A security model for developers
Software security is more important than ever, but developing secure applications is more confusing than ever. TLS, mTLS, RBAC, SAML, OAUTH, OWASP, GDPR, SASL, RSA, JWT, cookie, attack vector, DDoS, firewall, VPN, security groups, exploit, […]