I think one of the main disadvantages of Play’s design is the overuse of static methods in controllers. This causes hard to test controllers, long-running tests and decreases modularisation. So, how can we use Spring to rescue us?
First of all, don’t get me wrong: I like the Play Framework a lot. I just think there are chances for optimisation if it comes to testing and modularisation.
After searching for Spring integration in Play Framework 2 I discovered this demo by Guillaume Bort on how to combine Spring and Play 2. The name of this repository suggests that is does work with Play 2.0 but it only works with Play 2.1 because the so called managed controller classes instantiation is only available on Play 2.1 branch. And in fact with Play 2.1 you can easily integrate every dependency injection framework you want by implementing a
getControllerInstance method on a Global object.
I want to show you how to integrate Spring into your Play 2.0.x application.
There is already a Spring module for Play 2. But I don’t like the fact that you have to use at least two lines of XML to get annotation-based configuration and component-scanning in place. As Chris Beams states in his slides about modern enterpise app config: “this is kind of ironic”. If you like XML files you can also try this module: play-2.0-spring-module. I prefer annotation-based configuration. But this module inspired my solution a lot.
Ok, the goal is to autowire our controllers. Therefore, you have to intercept the controller creation by Play in some decent way. The trick is to add a stupid
ControllerFactory that delegates static controller calls to non-static controller classes and let all routes go through this factory.
1 2 3 4 5 6
The controllers can be non-static and therefore also instantiated by an application context. In the next step you simply bootstrap an application context in your Global object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
With this you get an application context everytime Play starts. In the last step you autowire every controller in the static delegating methods of
1 2 3 4 5 6 7
Now you have fully fledged Spring integration in your Play application and the
Application controller can be autowired.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
You can find the full example project with more explanations there: play20-spring-integration