Oct
31
2006
14

Using Spring 2.0 AOP to implement web-request interception

I was teaching another class yesterday and the focus was mostly on the web-tier. This is where we usually spend a lot of time on Spring Web MVC and Spring Web Flow and if the class is interested we also do a bit of Acegi Security (although in this half hour we’re only scratching the surface of it).

One of the subjects in the web module is using HandlerInterceptors to transparently add behavior to web requests. HandlerInterceptors are nice little components that allow you to for example do simple authentication, populate the Log4J Nested Diagnostics Context is populate the model returned by a controller with information each and every view needs (such as user information or information about the current state of the system).

When we touch on HandlerInterceptors, most of the time the audience pretty much sees the resemblance with Servlet Filters immediately. The resemblance is certainly there. There are pretty good reasons why we initially choose for a special purpose interception mechanism (Servlet Filters and EJB 2.x & 1.x transaction and security management are also good examples of special purpose interception mechanisms).

One of the guys in class asked me if it was possible to implement Spring’s HandlerInterceptor mechanism using Spring’s new AOP functionality. Interesting question! Yes in fact it’s possible and that’s what I’ll be reviewing in this post.

The traditional approach (using HandlerInterceptors)

Let’s first review a short example of how we use HandlerInterceptors to transparently do something completely orthogonal to any request in the system.


/**
* Simple handler interceptor that outputs some logging right
* before the request is executed.
*
* @author Alef Arendsen
*/
public class OldSchoolRequestMonitor implements HandlerInterceptor {

public void afterCompletion(HttpServletRequest req,
HttpServletResponse res, Object handler, Exception ex)
throws Exception {
}

public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView mav)
throws Exception {
}

/**
* Here we're just implementing the preHandle method
* to output a bit of logging data *before* the request
* is handled.
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse arg1, Object response) throws Exception {
System.out.println("Request came in (using a HandlerInterceptor now)");
return true;
}
}

This interceptor is actually pretty straightforward. Plugging it in to let it intercept requests is arguably even simpler. After we’ve created our web application infrastructure (web.xml and ***-servlet.xml file), we’re ready to put it to work:



In short, the process after we’ve added the above code to our ***-servlet.xml file is as follows:

  1. A request (/helloWorld.html for example) comes in, the DispatcherServlet picks it up
  2. Using a handler mapping, the DispatcherServlet determines the execution chain of this request (what handlers or controller are there to handle this request, are there any interceptors, et cetera)
  3. It finds there is an interceptor (the one configured alongside the HandlerMapping) and a controller (the HelloWorldController) that both match
  4. The DispatcherServlet starts to execute both in turn and that’s how the HandlerInterceptor is allowed to intercept requests

Additional features the HandlerInterceptor class has are the following:

  • - it allows modification of the request processing chain by returning true or false from the preHandle() method. If you return false, the execution will halt
  • - it allows you to modify the ModelAndView instance returned by controllers in the postHandle() method, which is pretty neat because you can do all kinds of fancy stuff there
  • - it allows you to inspect exceptions thrown from the handleRequest() method implemented by Controllers

Using simple (Spring 2.0) plain object advice

So now for the Spring 2.0 approach with plain objects and AOP. Instead of implementing the HandlerInterceptor interface, we’re going to reuse a simple object that doesn’t have any specific Spring interfaces:


public class RequestMonitor {

public void logRequest() {
System.out.println("Request came in (using a simple Spring AOP 2.0 advice now)");
}

}

So the requirement here basically is that we want to log every web request. Let’s express that using the usual (AOP) suspects. First, our pointcut:


expression="execution(* org.springframework.web.servlet.mvc.Controller+.handleRequest(..))"/>

Review this pointcut carefully and think what it actually means. How we usually explain things to people is to read the aspect as follows: a web request (notice the name of the pointcut) is the execution of the handleRequest method on any Controller.

Now we need to configure a piece of advice. Since the advice itself is a simple object, the only thing we need to do is configuring it in Spring:



Linking the advice object and the pointcut is a bit more completed, but actually not that difficult either. We want to log incoming requests before the are handled (as stated earlier in the post). So we will be using before advice. We want to call the logRequest() method as seen in the RequestMonitor class defined above. And we want to do that if the webRequest pointcut matches (in other words, for every web request):





The entire AOP configuration needs to be wrapped inside an element, but that’s just details for now. The result of the two different ways of implemented the interceptor is exactly the same, so in other words, yes, implement web-level interceptor using AOP is perfectly possible.

Somewhat more advanced advice

Of course I hear everybody saying right now: “so what about access to the request, the response, the model, et cetera)!”. Well, that’s something I won’t be able to cover in this entry, as I’m almost out of time. I’ll post a more advanced sample later this week or next week.

Conclusion

So yes, it’s possible to get basic HandlerInterceptor behavior in place with Spring AOP as well. The question of course still remains if all of the things we can do with a HandlerInterceptor are also possible using Spring AOP. We’ll see that in my next entry. We’ll also touch on the subject of whether or not this is a good thing to do.

[i] requestmonitor-1.0.zip – the sample application showing both ways of monitoring web requests (note that for the sample to work, you need to put the Spring 2 jar in the lib directory as well as the AspectJ Weaver jar. I’ve left those out, otherwise the file size would grow too big.

Written by Alef in: Java-related, Spring |
Oct
17
2006
6

Block you agendas – Amsterdam Java Meetup – 26/01 (2007)

images1.jpg

Agendas are filling up rapidly, so I decided to just reserve a date already for the next Java Meetup. I haven’t decided on a location yet, although the Jaren (where we had a few drinks last September 29 was pretty good IMO.

Maybe Erik B. will bring his latest gadget with yet even more networking options; so this time he can fill the parking meter without having to leave the cafe (Erik, maybe its a good idea to hitch a ride with somebody or come by train, so you don’t have to fill the meter again :) ). Maybe we’ll also have another encounter with the mysterious Russian, who knows.

In any case, block January 26th (2007 that is) for the next Amsterdam Java Meetup!

Written by Alef in: Java-related |
Oct
11
2006
3

I spy with my little eye

So Google finally managed to get their hands on some recent and hi-res satellite images from parts in the Netherlands other than just the center of Amsterdam.

Untitled.png

So you can finally see me lying in my hammock in my backyard :) .

I think Google Maps and Google Earth are really terrific. Today this New York Yankee pitcher (well, that’s what the news says anyway), flew his airplane into an skyscraper in New York while having one of his flying lessons (I would immediately award him with this year’s Darwin award). The news used Google Earth and Google Maps to show exactly which building it was. That’s something else than having a helicopter hovering over the East River (that was it, right?).

It is striking thouhg IMO that this unfaithful event is all over the news; not only in the States, but even here in the Netherlands. Of course, the event bears a bit of a resemblence to those of 9/11, but the media certainly seems to exagerating here a bit; or is it just me.

Oh, by the way, this is a link to Google Maps for my place.

Written by Alef in: At home |
Oct
05
2006
5

On the ServiceLocatorFactoryBean, DLAs and the sustainability of code and design

Phew that was a long title…

images.jpg
I recently visited a client to fix an issue with their one of their applications and fortunately after a couple of hours, this was already done. We had originally scheduled 2 days on-site and the client asked me if I wanted to use the time I had left to do some architectural analysis of their application. Clients frequently ask us to do something like this, because they appreciate good design. It’s definitely not only the coders that actually appreciate good design, but definitely also a lot of managers nowadays. This time I was specifically asked to review the maintainability of the design. They had pieces of code coming in from various locations all over the world and wanted to ensure that the original design (even with the continuous stream of new code) was kept in place. We at Interface21 use something called design level assertions (DLAs) to do exactly this.

Design Level What??

I usually just start working my way through the codebase (as the code ultimately reflects the design best–if the client is happy with the codebase that is :) ). I do this together with some developers hinting at changes here and there, asking questions about the rationale behind certain decisions and I always jot down a few notes. Later on I use AspectJ to capture the design in some rules. These rules are what we call design level assertions.

The tell you things about the design and can be used alongside the actual codebase to see if the original design rules still hold for the codebase. Let’s start with a short example: one of the specific things the client wanted to check was the usage of dependency lookups in the application. I quickly wrote myself a DLA for this to check if they used dependency injection in all of their application. This would be their first DLA and using this, they could quickly see if any newcomers to the project would mess up the codebase.

pointcut inMyApp(): within(com.mycompany.myapp..*);

pointcut dependencyLookup() : call(* org.springframework.beans.factory.BeanFactory+.*(..)) && inMyApp();

Read this as follows: a dependency lookup is a call to any method on a bean factory from my application. The next thing to do is to declare a warning because we want pick this up during compilation and inside our Eclipse IDE.

declare warning dependencyLookup() : "Maybe you shouldn't use dependency lookups but DI";

Design level assertions can be captured in several ways. Using a tool like Checkstyle might also do the trick. I prefer AspectJ to create DLAs, as those design-level assertions actually have more of a code feel, rather than a document feel to them. When your design level assertions are part of your codebase, just as your test suite, it’s much more easy (errr, easier) to maintain them and keep them in synch with the changes that might occur to the design. Unfortunately the AspectJ development tools don’t yet fully support refactorings, so there still is some manual work in that area, but it certainly isn’t a Word document. Second of all, you can actually check the design level assertions during compilation instead of having to add an extra build step. Last but not least, you’ll actually be able to use the DLAs written using AspectJ inside your Eclipse environment. This means you’ll have nice error and warning messages inside your Eclipse IDE that reflect failed (design level) assertions. Nope, no eye candy for now, I don’t have time to take screenshots of Eclipse right now :) .

schoolrules.gif

The result of this DLA

After I created the DLA that checks for dependency lookups, I ran it across the client’s codebase. As the codebase was rather large, I used the iajc[i] Ant task instead of the AJDT integration that give you these oh-so nice error messages inside Eclipse.

To my surprise, they had more than 200 dependency lookups in their codebase (that was about 2500 classes big). Something must have gone wrong with the DLA I thought. I reviewed the warnings I got and they were all correct. There were dependency lookups all over the place!!

After investigating a bit more, I came to the conclusion that they had used dependency lookups to retrieve a prototype bean from the bean factory. They simply couldn’t do with a singleton, because the object (or rather, objects) they had to lookup maintained state across multiple method calls (in other words, weren’t thread-safe). I thought about a possible solution, so that we could still use the DLAs, but without seeing all those dependency lookups, all of which were actually justified.

Introducing a service locator

The final solution I opted for using a dedicated service locator would remove all the direct dependency lookups and move them all into one single place.

public class ProcessFactory implements BeanFactoryAware {

private BeanFactory beanFactory; // setter omitted

public Process createProcess(String processId) {
return this.beanFactory.getBean(processId);
}
}

Instead of issuing calls to BeanFactory.getBean() directly inside the code in the application, I replaced all those calls with calls to the ProcessFactory (after having injected the ProcessFactory of course). This way, the application could still create process of all kinds of types (declared in the application context) and yet still adhere to the rules set out earlier.

Modifying our DLA

There is still one tiny issue though. We’ve removed all kinds of dependency lookups from our application, but we’ve also introduced one (the one in the ProcessCreator). So we need to slightly modify our DLA to exclude this one lookup:

pointcut inProcessCreator within(com.mycompany.myapp.mypackage.ProcessCreator);

pointcut inMyApp(): within(com.mycompany.myapp..*);

pointcut dependencyLookup() :
call(* org.springframework.beans.factory.BeanFactory+.*(..)) &&
inMyApp() && !inProcessCreator();

As you can see, we only need to slight modify our DLA to reflect the changes we’ve made.

I quickly ran the DLA across the codebase again, and I only got a few warnings this time. I quickly refactored those and comitted the code the version control system.

Conclusion

As you can see, there certainly is such a thing as design for maintenance. Using DLAs and a dedicated service locator, we were able to decouple our application from the Spring APIs completely and create a less fragile and more sustainable design. Next to spreading your code across packages, that often correspond to modules or layers in your system, other things like adding annotations to certain classes (or in environment in which you’re not able to use Java 1.5 yet, a marker interface) might also help to better embed the rules of the game in the codebase; especially if you’re using DLAs with AspectJ for example.

tow0009.jpg

And what about the ServiceLocatorFactoryBean??

Ah, yes, I mentioned this in the title as well, didn’t I? Well, there’s a nice alternative to having to code your own service locator, as I did in the piece above. This is called the ServiceLocatorFactoryBean and it prevents you from having to do the lookup yourself. The first thing we do is throwing away the ProcessCreator class and replace it with a ProcessCreator interface:

public interface ProcessCreator {

Process createProcess(String processId);
}

This is what we’ll still be using in the component that need to get a hold of a process (so, in other words, in about 200 places in our client’s codebase). We do however still need to provide an implementation. This is what we’ll do using the ServiceLocatorFactoryBean:

class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">

value="com.mycompany.myapp.mypackage.ProcessCreator"/>

This is what we will inject, instead of the concrete ProcessCreator class we’ve used in the previous example.

p.s. If you’re still not sure (and I wouldn’t be surprised) what DLAs actually are and how you can implement them using AspectJ, please leave a comment below and I might write some more about it. [shameless-plug]Of course you can also take a Core AOP[ii] course :) [/shameless-plug]

[i] The Eclipse iajc task
[ii] Core AOP – Simplifying Enterprise Application Development with AOP

Written by Alef in: Java-related, Technology |
Oct
05
2006
0

Adrian Colyer to speak at NL-JUG / Spring 2.0 released

A small combined post about a couple of interesting events.

The first is already behind us. Last Tuesday we released Spring 2.0 and thanks to all the hard work of Juergen, Rob, Rick and many others, we have seen a lot of enthusiasm around this release already. Rod mentioned on his blog a couple of hours ago the release was downloaded more than 10.000 times already! This is pretty amazing!

spring20.png

Next Wednesday, the bi-annual NL-JUG conference will be held again. At this event, Adrian Colyer will deliver a keynote about the vocabulary of enterprise applications. He’ll probably touch on Spring 2.0 too, so if you’re interested please drop by! He’s going to talk about AspectJ too by the way. There are several other I21 people present at the conference too, so it should be fun!

On to the next big event: the release of Spring Web Flow. Keith noted at TheServerSide that 1.0 version of Spring Web Flow will most likely be released somewhere in the next two weeks as well. So October is proving to be a pretty interesting month.

Written by Alef in: Java-related, Spring, Technology |

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com