In order to develop modular Java applications, the use of a dependency injection framework is essential. In this post I show how to combine Spring with Play Framework: setting it up, how to use it for action composition and in unit tests and issues that I have found.
Note: I’m using Play framework version 2.2.x and Spring 3.2.5
Library dependency
Add Spring dependency to your project in build.sbt
:
In /conf
folder add components.xml
Spring configuration.
Controller
Since Play version 2.1 [^version2.1] controller don’t have to be static anymore, which makes it possible to inject them. In your Global.java
class override following methods:
Now you can use your controllers by annotating them (I prefer to call my Play controllers “Controllers” and put them in a different package than the default modules
package suggested by the official Play documentation):
In order to enable Spring to wire your controller, you need to configure the base package in components.xml
, for example, if the package is named api.controllers
you could set it up by adding:
@Autowired beans
You can now wire your bean into your classes. I prefer to put most business logic into services and wire them as needed.
Action composition
One important feature of Play is action composition 1. As Action are going to get wired in it is important to set the correct bean scope2. If no scope is specified, Spring will use the default one which is “singleton”, which will cause weird behavior. Actions need to be created with each instance, so “prototype” is the correct one:
Unit tests
In order to run unit tests with wired beans, we need to annotate our spring configuration and class runner:
Issues
Last updated: February 2014
Using Play and Spring together, you may encounter following (strange) error message:
java.lang.VerifyError: Stack map does not match the one at exception handler
This seems to happen when using injected classes in a try-catch context. A solution for me was to set _JAVA_OPTIONS
like this:
export _JAVA_OPTIONS="-XX:-UseSplitVerifier"
More about this bug can be found here: https://github.com/playframework/playframework/issues/1966
With this, I hope you will be able to use Spring in your Play project and keep it nicely modularised.
Thanks for reading
I hope you enjoyed reading this post. If you have comments, questions or found a bug please let me know, either in the comments below or contact me directly.