An Autowired handler for Spring MVC

Disclaimer: I’m no Java expert. This is my first commercial project in Java, but I thought that this was so useful I had to share.

To the best of my knowledge Spring MVC resolves arguments to request handlers (@Controller methods annotated with @RequestMapping) using what is essentially a large switch statement based on type/argument-name, etc. When it encounters one of our own beans it will make a best attempt and instantiate for us a new instance using the default constructor (if present!). This article does an excellent job of explaining the internals.

This poses a problem when we want resolve an object either a) without a default constructor or b) with a graph of Spring IoC dependencies (@Autowired fields, etc). After searching for a while I came across one article explaining why this was a good idea and how it would look in practice, but alas no code… however it looked too good to pass-up, so with the help of this article I implemented a customer web argument resolver with accompanying annotation. Here is the class:

public class AutowiredHandlerAnnotationArgumentResolver extends WebApplicationObjectSupport implements HandlerMethodArgumentResolver {

 @Override
 public boolean supportsParameter(MethodParameter paramMethodParameter) {
  return contains(paramMethodParameter.getParameterAnnotations(), AutowiredHandler.class);
 }

 private boolean contains(Annotation[] parameterAnnotations, Class<AutowiredHandler> clazz) {
  for (Annotation annotation : parameterAnnotations) {
   if (clazz.isInstance(annotation)) {
    return true;
   }
  }
  return false;
 }

 @Override
 public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
    NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
  WebApplicationContext ctx = getWebApplicationContext();
  return ctx.getBean(parameter.getParameterType());
 }
}

And here the annotation:

@Target(java.lang.annotation.ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutowiredHandler {
}

You will of course need to import all the correct packages, as they were omitted for brevity (otherwise we’d be here all night). Once they’re in place you simply register the argument resolver under the mvc:annotation-driven node of dispatcher-servlet.xml:

<mvc:annotation-driven>
 <mvc:argument-resolvers>
  <bean
  class="co.uk.package.AutowiredHandlerAnnotationArgumentResolver" />
 </mvc:argument-resolvers>
</mvc:annotation-driven>

… although part of me wishes you didn’t have to register anything anywhere, but there you go. After paying homage to the Spring XML gods you have all the power of the IoC dependency resolution framework simply by annotating an argument with the AutowiredHandler:

@RequestMapping(value = { "/exit", "/logout" }, method = RequestMethod.GET)
public String ourHelloWorldHandler(@AutowiredHandler HelloWorldService service, Model model,
 HttpSession session) {
 // use service...
}

The development effort essentially resolved around finding the right base class in order to get easy access to IoC (via inherited getApplicationContext), reflecting to find the annotation and implementing the correct interface. Simples.

We frequently use it for resolving classes that have their own dependency tree that are only required for the handler method in question. I hope it proves useful to others out there.

C

MancJS and general JS goodness

I recently had a write-up of mine published on my employer’s portal, so I figured it’d be a reasonable first post to this blog so that I could expand upon it later:

http://ao.com/world/mancjs-welcome-world-web-dev/

I’m a big fan of DRY, but sometimes de-normalised data has it’s role to play, so here’s the article for those that are click-lazy::

“This is why I joined AO. That and the free chocolate. A software developer hailing from the demi-city of Lancaster, I needed to know what was happening out there in the world of development. I needed to learn for both the fun of it, to broaden my mind, and to work better in my day-to-day nine-to-five.

This month’s MancJS, as usual, did not disappoint. The standard fixtures were present – neat venue, free pizza, beer, talks, a heavy AO-presence and the optional pub afterwards. All together pretty much guarantee a good night of codery; not forgetting the people that live and breathe the most popular language in the world by most metrics – Javascript.

Manc JS

This Wednesday’s talks were:

‘What I know about React’ by Joe Critchley (@joecritchley‎)

‘An introduction to Koa’ by Thom Seddon (@ThomSeddon)

Joe took a diary-style approach for his talk on exploring the React micro-framework, describing a journey from initial scepticism (separation of concerns being a… concern) to ‘it’s starting to click and I want to know more’ over a period of two months.  My initial worries – the procedural nature, JSX, maintaining a separation of concerns – were assuaged. I much enjoyed his presentation style and honesty, and he did a good job of convincing me that React would be something to consider when creating UI’s where performance, componentisation and/or declarative style are a high priority.

Thom’s topic was the Node.JS framework Koa, the spiritual successor to the ever-popular Express. Wisely he took a ground-up approach, explaining through the use of examples how the new language feature ‘generators’ removed the need for the plethora of callbacks, how ‘Co’ managed the generator workflow and how Koa sits on top of these two to provide a succinct HTTP programming style. You could say we got three topics for one talk.

1

I came away with a level of conviction that Javascript will become a great language (if arguably it isn’t already) and highly optimistic for its future. I would definitely recommend the event to those that appreciate frameworks and programming languages.

Next month promises to include a talk on an Erlang trans-compiler for Javascript by the author of said compiler. I know I’ll be there.”

It’s interesting this shift towards Javascript. I don’t doubt it’s an unstoppable beast, but from a purely technical perspective does it merit it?

Maybe my view isn’t quite up-to-date, but I am reminded of the lectures by Mr. Crockford, and apparently he knows his stuff:

http://www.yuiblog.com/crockford/

Over and out for now.

C