Having fun with Spring AOP
Thursday 24 August 2006 @ 1:46 pm
Filed under:

Aspect Oriented Programming for me always has been something that is theoretically beautiful but in practice unfeasible to apply: A good idea that buried itself by bad examples and complex implementations. Until Google pointed me to this great article about AspectJ5 and its integration into the Spring Framework. Actually I was looking for some EJB3 related Spring material but I ended up reading probably one of the first articles that after finishing left me with a ‘yep, I really want to do AOP, even at home’-kind of feelings.

The whole idea is actually super simple. AspectJ has been extended with two very handy mechanisms: a run time (actually load time) weaving engine and support for aspects that are expressed in Java 5 annotations. Using AspectJ’s API we do not have to rely on a separate compiler but the process of aspect weaving can be initiated whenever we like. And that is exactly the trick Spring is using. Aspects are actually Spring managed instantiations that influence other spring managed beans. When Spring is loading bean classes, cross cutting aspects are weaved in like a breeze.So, I grabbed the latest Spring release (2.0), read some more background information and started right away. Within minutes an AspectJ based interception of a completely meaningless but spring managed hello world bean was up and running. Cool! Hello world never has been so enlighting. To make things a bit more practical, I tried to implement a typical architectural constraint like “Methods on classes belonging to the an applications data access layer may only be called through methods of classes belong to the service layer.”. Normally this constraint is written down by software designers in a plain ms-word or odf ‘thou shall not’-document,  but using Spring AOP it can be expressed in a bit of xml (yep, Spring ….) and a Java class. ( I am not going to argue the semantic practicalities and implications of this constraint, for me it is just an example to express the ‘aha feeling’.) Okay, here are some interesting pieces of the class I wrote. Full details can be found in this posts attachment (acsa.zip). @Aspect public class SystemLayeringAspect { // ……define the pointcuts to identify different layers @Pointcut(”within(com.logicacmg..*.service.*)”) public void inServiceLayer() { }@Pointcut(”within(com.logicacmg..*.dao.*)”) public void inDataLayer() { }

add some thread local sugar for administrative purpose private static ThreadLocal tlServiceCount = new ThreadLocal() {  protected Integer initialValue() { return 0; }

};

define the advice to register the usage of service method calls@Around(”inServiceLayer()”)public Object serviceUsage(ProceedingJoinPoint thisJoinPoint) throws Throwable {

  tlServiceCount.set(tlServiceCount.get() + 1);

  Object result = thisJoinPoint.proceed();

  tlServiceCount.set(tlServiceCount.get() - 1);

  return result;

}

and define the advice how to deal with data access calls @Before(”inDataLayer() && this(dao)”)public void dataUsage(Object dao) throws Throwable {

  if (tlServiceCount.get() == 0) {

    throw new ArchitecturalConstraintFailed(dao + ” can not be accessed directly”);

  }

}

Note, the difference in the advice types. The service advice needs to work around the actual method call, the dao advice does its job only upfront.That’s it. simply plug it into your Spring application context after the and off you go.  ApplicationContext context = new ClassPathXmlApplicationContext(”application-context.xml”);
ExampleService service = (ExampleService) context.getBean(”helloService”);
ExampleHelper helper = (ExampleHelper) context.getBean(”helloHelper”);

ExampleService service = (ExampleService) context.getBean(”helloService”);

ExampleHelper helper = (ExampleHelper) context.getBean(”helloHelper”);

 

service.doSomething();

try {  helper.helpABit();

} catch (ArchitecturalConstraintFailed afailed) {

  System.out.println(”yep catched ” + afailed);

}

In the example used to test the architectural constraint, a dao is called through a helper bean. Calling the helper directly will result in a runtime failure, calling it through the service is no problem. Seems aspect orientation has finally been made easy. Although, one should be aware of the behaviour that aspects are honoured only by java classes that are loaded through Spring. So be careful with the new operator. But besides that, all I can advice is to have fun and make good use of it.  

 

— By Okke van 't Verlaat     PermaLink

3 Responses to “Having fun with Spring AOP”

  1. Craig Walls Says:

    Just to be clear…a quick glance at your code tells me that you’re using the tag. That tells me a bit more about how your aspects are woven.

    You see, if you’re using , then you’re actually not using as much of AspectJ as you may think. You’re only using the @AspectJ annotations, but Spring is interpreting those annotations to build Spring-style AOP proxies under the covers.

    On the other hand, if you were running this in an AspectJ runtime, the aspects would be interpreted by AspectJ.

    This is an important distinction, because the Spring version is a bit limiting. @AspectJ aspects that are interpreted by Spring are turned into Spring-style proxies which means that you’re limited to method interception. @AspectJ aspects, are more powerful and allow more advanced AOP techniques (constructor interception comes to mind, but there are more).

  2. Craig Walls Says:

    The empty spots in my previous comment should have been the <aop:aspectj-autoproxy> tag…

  3. Okke Says:

    Yep, I indeed used the Tag (Hey Luke, may the Tag be with you :-) ). And I’m indeed aware of the fact I’m missing the more advanced (or should I say powerful) pointcut designators. But, isn’t that inheritent of using Spring?

Leave a Reply


Menu


Sha256 mining

Blog Categories

Browse by Date
August 2006
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
28293031EC

Upcoming Events

Monthly Archives

Recent Comments

Links


XML Feeds Option


Get Firefox  Powered by WordPress

code validations
Valid RSS 2.0  Valid Atom 0.3
Valid W3C XHTML 1.0  Valid W3C CSS