Okay, good you made it past the title. I was at a client that has been a long-time Spring user. Some of the client’s stuff needs a revision and as part of this revision Spring 2.0 AOP was introduced in some places. Today, for the group of developers I shortly touch on some of the basic differences between AOP in Spring 1.x and AOP in Spring 2.0. I figured it would be good to post the examples online.
Let’s first set the stage for the example (and please read this carefully): an exception thrown from a service method should be emailed to an administrator.
Here’s an example of a service method:
package com.mycompany.myapp.service;
public interface DrinkingService {
void doIt();
}
with a corresponding implementation:
package com.mycompany.myapp.service;
public class DrinkingServiceImpl implements DrinkingService {
public void doIt() {
throw new IllegalStateException("I have a hangover so please don't bother me!");
}
}
As you can see, it’s in an illegal state at the moment (probably because the service drank a bit too much Limoncello or something). Normally service wouldn’t do this, but this time of the year (when leaves start falling and days are shortening), I can definitely imagine services grab the bottle.
Anyway, let’s continue. The requirement was to notify an administrator (by email) about any exception occurring inside a service. DrinkingServiceImpl is just one example of a service and because there probably are more services in our application, we’re going to use AOP to implement this specific requirements. Think about the 1:1 principle, separation of concerns (SoC), Don’t Repeat Yourself (DRY) and all that crap…
There are several ways of solving this. Let’s examine them one by one.
Emailing the exception using Spring 1.x
Suppose you’re stuck at Spring 1.2. Then the way to go is using a ProxyFactoryBean. Using this Spring class, you can configure interceptors in order to advise certain methods.
This piece of Spring configuration configures a ProxyFactoryBean and one interceptor, which in this case is a bean called exceptionAdvice. Configuring something like this, obtaining the service bean and calling a method on the service bean, will actually cause the interceptor to ‘run’.
The interceptor (the EmailOnExceptionAdvice) is actually an instance of ThrowsAdvice, which means it only gets called when an exception occurs inside a method call on the drinkingServiceTarget. There’s only one method, which in this case takes an Exception.
public class EmailOnExceptionAdvice implements ThrowsAdvice {
public void afterThrowing(Exception e) {
System.out.println("Email the exception!");
// TODO email the exception to an administrator
}
}
So, one more time:
- The ProxyFactoryBean creates a proxy wrapping the target object (in this case a DrinkingServiceImpl)
- The ProxyFactoryBean also configures an interceptor that acts on any exception occurring inside the service
- The interceptor (advice) receives notice of exceptions occurring and emails them to an administrator
As you can see (run the example if you want more insight), the requirement (exceptions thrown from a service method should be emailed to an administrator) has successfully been implemented!
Note that there’s absolutely no reason to keep yourself from upgrading to Spring 2.0. The new Spring version of in 95% of the cases fully backward-compatible with the 1.x-line and spring-2.0.jar should in most cases be a drop-in replacement for the spring-1.2.7.jar for example.
Emailing the exception using Spring 2.0 and the old advice
You might be wondering why we’ve created Spring 2.0 and enhanced the AOP capabilities so much if things are that easy using Spring 1.x. Well, there actually are a lot of reasons, some of which will probably get clear after I’ve introduced the new approach. Let’s first revisit our initial requirement:
an exception thrown from a service method should be emailed to an administrator.
Although this requirement has been implemented correctly, the way we did it might sound kind of low-level. We used proxy factories, interceptors, advice, target objects and much more, all to email an exception to an administrator. Using Spring 2.0, we’ll see that all these infrastructural components more or less disappear, allowing us to make the code look more like the design while still successfully implementing the requirement.
To not take too big a step, in the new version, we’ll reuse our old advice and we’ll just change the configuration a bit. We’ll start off by defining a pointcut:
What this pointcuts says is the following: a serviceMethod is the execution of any method in service package of my application. That’s what I call ‘make the code look like the design’. The next thing we’ll do is attach the previously created advice to our pointcut and we’re done (this is what we’re doing using an aop:advisor element. The final configuration looks like this (in other words, no more ProxyFactoryBeans).
<code> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* com.mycompany.myapp.service..*.*(..))" /> <aop:advisor pointcut-ref="serviceMethod" advice-ref="exceptionAdvice" /> </aop:config> <bean id="exceptionAdvice" class="com.mycompany.myapp.util.EmailOnExceptionAdvice" /> <bean id="service" class="com.mycompany.myapp.service.DrinkingServiceImpl" /> </code>
And now for a completely Spring-less approach
In the previous two solutions, we used special Spring classes to implement our advice. There is a third approach not requiring you to implement any Spring-specific interfaces. This is what we called the ‘POJO advice’ approach. Using the POJO advice approach, you can use any existing class that doesn’t have to have any references to Spring whatsoever to serve as an advice. Okay, let’s change the exception advice to a POJO advice first:
<code>
public class ExceptionEmailer {
public void emailException(Exception exception) {
System.out.println("In Emailer");
// TODO implement emailing functionality
}
}
</code>
This should be straightforward to understand. Upon the catching of an exception the emailException method should be called. Again, we’re going to try to make the code look as much like the design as possible. Here’s how we can do this using Spring AOP in version 2.0:
<code> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* com.mycompany.myapp.service.*.*(..))" /> <aop:aspect ref="exceptionEmailer"> <aop:after-throwing throwing="exception" pointcut-ref="serviceMethod" method="emailException"/> </aop:aspect> </aop:config> </code>
Let’s have a look at how the aspect reads: after-throwing an exception from any serviceMethod, call the emailException method on the exceptionEmailer. Pretty straightforward if I may say so myself. I can remember Gregor Hohpe telling me once that he tried to code in such as way that he could show his code to non-technical managers. Well, IMO this certainly is a way of doing this!
Other ways of doing this
There are still plenty of other ways of making sure an email is sent after an exception has been raised. One of the ways of using AspectJ, which will result in code resembling the title of this post. Maybe I’ll write about the other approaches some other day. First, I’ll have to write a follow-up to my example about how to use AOP to intercept web requests.
p.s. Here are the sample sources. Just as with the previous post, remember that you should include spring-2.0.jar and aspectjweaver.jar, otherwise things won’t work. I still haven’t found the time to get Maven2 done for these sample projects.

Thanks for the great articles on Spring AOP.
Suppose in the POJO ExceptionEmailer I want info about the service method in which the advice was thrown, like the service method name or the arguments it had.
Thanks Will,
There is a special argument you can include in the methodmethod called JoinPoint (from the org.aspectj package). This provides information on the method execution, such as the name of the method, et cetera.
So in other words, change the emailException(Exception e) method to emailException(JoinPoint jp, Exception e), Spring will automatically fill in the jp argument.
How to bind arguments to advice in a less generic way (ie not using the JoinPoint object) will be covered later on.
EmailOnExceptionAdvice#afterThrowing() should probably expect an Exception as parameter instead of DataAccessException. Seems like you fixed this in the example code already, but not in your post.
Anyway, another great example of Spring AOP.
Thanks Sapporo, I’ve fixed this in the post now as well.
hi Alef,
thanks for the article.
(even though the DrinkingServiceImpl does not compile…)
Herman
Hi Herman,
thanks for spotting this. I’ve fixed the code in the text. The zip file had the correct version (although, that is if you meant the MyService() method needed to be changed to doIt()).
…I just created a pom.xml file that allows you to build everything using Maven. No more reason to download spring-2.0.jar and aspectjweaver.jar manually. You can find the file on my blog: http://agilejava.com/blog/?p=77
Hi,
Just learning Spring aspects. I have the requirement to catch a DAO runtime exception that is not hidden within our business service layer. The exception is going all the way to the presentation layer and the client does not know how to handle this.
Can I use the ThrowsAdvice to catch these DAO runtime exceptions and simply throw a wrapper exception that the client knows how to deal with? Can ThrowsAdvice be used to wrapp the thrown exceptions?
Any comments much appreciated.
Thanks,
Greg
Hi Greg,
this is not very difficult: when using Spring 2.0 (I would definitely recommend this) you would have to the following inside a Spring XML file:
<aop :config>
<!– 1. Identify places where you think this is going to happen (in other words: where the exception should be ‘translated’ or ‘rethrown’). This is what you call a pointcut. –>
</aop><aop :aspect ref=”myExceptionTranslator”>
<aop :pointcut id=”serviceOperation” expression=”execution(* com.mycompany.service..*.*(..))”/>
<aop :after-throwing throwing=”exception” method=”translate”/>
</aop>
<bean id=”myExceptionTranslator” class=”com.mycompany.util.MyExceptionTranslator”/>
<bean id=”myService” class=”com.mycompany.service.MyService”/>
public class MyExceptionTranslator {
public void translate(MyFunnyRuntimeException e) {
throw new MyOtherFunnyRuntimeException(e);
}
}
Now remember: if you use Spring AOP, the advice will ONLY be applied to managed Spring beans (not to objects created by new()).
For more info on the pointcut expression language and AOP 2.0, look at the reference manual (http://static.springframework.org/spring/docs/2.5.x/reference/aop.html).
Let me know if you have any issues with it.
regards,
Alef
Thanks Alef, works like a charm :-).
Much appreciated,
Greg
No problem Greg,
glad I could help.
Hi Alef,
With my ‘after-throwing’ advice working I want to understand how ordering comes to play. The application I am working on has a few other aspects implementing around, before and now my after impl. I am not sure how ordering works implementing the Ordered interface and when I need to be concerned about ordering aspects.
Is ordering only applicable to the same advice type being invoked on the same pointcut? For example if the application has several after-throwing aspects on the same pointcut I can see ordering working as the one with the lowest order value is invoked first ect…
However, in this case the application has an around aspect providing Authorization on user role and method being invoked. If the user is not authorized to access the specified method an AuthorizationException is thrown. In this case I don’t want my after-throwing to convert this exception so I implemented the after-throwing advice to be aware of this AuthorizationException and simply rethrow. But, could I have used ordering to resolve this?
We also have aspect ‘arround’ advices providing method argument validation, transaction management ect. The application has one central AspectsOrderingConstants providing all the aspect ordering. But I am not sure how my after-throwing advice needs to respect the ordering if at all???
Any comments much appreciated.
Thanks,
Greg
I am using Spring AOP interceptor for a transaction as a business process. Plese guide me to immplement exceptions handleing to intrupt the interceptior stack by throwing exception
Regards
Sateesh Thumma