September 03, 2007

Spring @Transactional handling with AspectJ

Save yourself and skip past this if you don’t know what Spring, AspectJ or transactions are :)

Your mileage may vary. 

Here at Internet Towers we needed to have fine-grained control over where our Spring 2 application starts and ends database transactions. We use AOP to some extent already, but it just wraps around every handleRequest method on every edit-mode Controller. There’s built in support for annotations so that you can wrap a method in a transactional simply by annotating it with @Transactional and putting <tx:annotation-driven /> in the configuration file. Sounds pretty simple.

But this is achieved using Spring’s proxy objects (more on AOP proxies) wrapping around the original controller, which only work if the method to be transactional is public and called from outside (otherwise the object is calling itself and bypassing the proxy that’s wrapped around it). This isn't great because it means you can't even use it on a call to handleRequestInternal. The solution is to use full-blown AspectJ weaving, which supports the same @Transactional annotation but can weave into any method and can be called from inside or out.

There are two ways to weave the transaction code in: load-time and compile-time. Load-time needs extra arguments when the VM is loaded which sounds like it would be a lot of hassle to remember to reconfigure every VM the application is deployed on. The easier we can drop the application file into a server’s deploy directory, the better. Compile time is nicer as it’s then built into the application, so I've gone ahead with that. The following is a rough guide to what's needed.

Firstly you need AspectJ, mainly the jar files that come with it, and also to make sure you have spring-aspects.jar that comes with Spring.

Sample application context:

<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:aop="http://www.springframework.org/schema/aop">
<aop:spring-configured>
<bean id="annotationTransactionAspect" factory-method="aspectOf"
class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
<property name="transactionManager" ref="transactionManager"></property>
</bean>

<!-- the rest of your application here -->
</beans>

Super. That's all the configuration the application needs to understand the @Transactional annotation. Now to add the weaving into the compile process. We use Ant to build, and there's an Ant task to do this. With the right options it will weave into your compiled classes. After some looking around I found that it's enough to just specify Spring's spring-aspects.jar.

Sample build.xml:

<target name="compileAndWeave">
<path id="web-src.compile.class.path">
<!-- paths to any libraries needed for compiling, including AspectJ -->
<path refid="external.libs.path" />
</path>

<!-- compile your source as normal, into some directory -->
<javac srcdir="src"
destdir="build/classes-preweave"
classpathref="web-src.compile.class.path" />

<!-- load up the "iajc" task -->
<taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"
classpath="path/to/aspectj/aspectjtools.jar"/>


<!-- weave the just compiled classes from classes-preweave into classes -->
<iajc
inpath="build/classes-preweave"
destdir="build/classes"
classpathref="web-src.compile.class.path"
aspectpath="path/to/spring/spring-aspects.jar"
verbose="true" />
</target>

That was a bit long, but the first half of it is just the standard compiling stuff.

Anyway, drop your shiny packaged war file into Tomcat or whatever and it should just work, handling transactions according to the "transactionManager" bean wherever you add the @Transactional annotation. If you annotate a class it will work as if you annotated all the public methods in that class.

Good luck! 


- 2 comments by 1 or more people

  1. Rafael

    Hi,

    another basic AspectJ Spring example can be found here http://www.developers-blog.org/blog/default/2009/07/14/Spring-AspectJ .
    It describes a logger aspect.

    Rafael

    06 Aug 2009, 14:31

  2. Nick Howes

    Logging is another prime use for AOP – good article.

    06 Aug 2009, 14:35


Add a comment

Name
Email
Anti-Spam Question
My t-shirt is red. What colour is my t-shirt?
Anti-Spam Answer
Comment


Your IP address will be recorded. -

You can not use HTML, but you can use our special markup -

Trackbacks

September 2007

Mo Tu We Th Fr Sa Su
Aug |  Today  | Oct
               1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Search this blog

Tags

Galleries

Most recent comments

  • Logging is another prime use for AOP good article. by Nick Howes on this entry
  • Hi, another basic AspectJ Spring example can be found here http://www.developers–blog.org/blog/defau… by Rafael on this entry
  • Thanks Jam Hug. Hope you're well. I deleted your three duplicate comments for you. by Nick Howes on this entry
  • that wasn't funny at all. your standards are slipping. by james hughes on this entry

Blog archive

Loading…
Not signed in
Sign in

Powered by BlogBuilder
© MMXIV