Tuesday 3 September 2013

Abusing dependency injection for fun and profit!

Using Spring for dependency injection can do a lot more than just put together your singleton services how you need them, optionally tweaking them for different environments based on a configuration file.

Oh, the DI in Spring can do so much more fun than just that.

Let’s say, just as a “hypothetical” example, that you’re working with a controller and service interface in a prepackaged JAR that you either can’t modify, or would have to go through a far amount of headache to change. Specifically, you’re implementing the service interface, and you know it will be called from the controller.

You take on a new task that requires access to the HttpServletRequest. Okay, you think, I’ll just get it from the FacesContext, until you remember that this module isn’t using JSF (and you can’t make it—not your controller, remember?). You can read the controller source and see that the method that’s calling your service uses the HttpServletRequest, but it’s not a parameter on the service method.

Barring modifying the JAR, there’s a surprising, and easy, way to get at it: inject it. I kid you not, this works.

That’s seriously all there is to it. You can inject anything higher on the call stack, though I suspect there needs to be only one instance of it. The HttpServletRequest gets updated with each request, even though MyService has been left in the default singleton scope. I wouldn’t recommend doing this simply because you can, though, for the sake of not having to pass the HttpServletRequest as a parameter. Injection breeds reflection, which is a crapton more logic, processing time, and memory usage, than simply passing a reference down the call stack. It also opens you up to debugging hell, particularly if you inject something that you then modify.

Use this with care, is what I’m saying, only when you have no other choice.

No comments:

Post a Comment