Having fun with Spring AOP II
Wednesday 6 September 2006 @ 5:42 pm
Filed under:

After my initial explorations of the AspectJ-support offered by Spring, someone (actually, I think it was google again) pointed me to this article about the drawbacks of proxied aop. A good read written by Vincent Partington that shows the internals of  how and why a proxy based aop framework can ignore your carefully injected aspects. A ‘must-be-aware-of’ for every Spring 2.0 user!

One commenter on Vincent’s entry suggested one could use the not so stunning but efficient AopContext.getCurrentProxy() call instead of refering to the ‘this‘ pointer. Besides being not beautiful (actually it is butt ugly but that’s a matter of taste which reminds me that programming just like cooking is actually all about (good) taste), getting hold of a proxied twin is in complete contradiction with all principles of aop: Code and cross cutting concerns should be seperated. The fact code needs to be aware of being proxied is more a showstopper than a workaround.

Nevertheless, once accepted this contradictious aproach, the idea came in mind to address this as just an aspect of implementation, an architectural constraint so to speak: ‘Every class or method that is subject of being proxied must be aware of its proxy object‘ (Note, I still do not agree with this rather bold statement, it is just a hypothetical aspect that I’m using for the sake of the nation to have some fun with Spring AOP). How can such an aspect being implemented using Springs AOP features?
First of all, somehow a mechanism must be in place to denote proxy aware classes. To do so, I introduced a special annotation:

public @interface Proxied {}

And of course some point cuts reflecting the usage of this annotation are required:

@Pointcut(”@within(com.logicacmg.acsa.annotations.Proxied)”)
public void withinProxiedType() {}

@Pointcut(”@annotation(com.logicacmg.acsa.annotations.Proxied)”)
public void executingProxiedMethod() {}

The first pointcut refers to classes declared with the @Proxied annotation, the second one refers to the execution of methods decorated with this annotation. Note the subtile difference, the second pointcut gives a fine grained approach were to intercept and were not.

After the pointcut definitions, it is time for some goofy advice how to deal with the proxied execution of methods:

@Before(”(withinProxiedType() || executingProxiedMethod()) && this(proxy)”)
public void beAwareOfProxiedExecution(JoinPoint jp, Object proxy) throws Throwable {
  // ….. ????
}

A dirty (but what the hack, the whole problem smells) trick injecting the proxy into the usual suspecious subjects can be used at the // ….. ???? location. And for that, I’ve mixed the advice with some reflection sugar under the assumption every proxy aware class has declared a member field called ‘proxy’. The code is to long to post here but without field caching and exception catching it looks like this:

jp.getTarget().getClass().getField(”proxy”).set(jp.getTarget(), proxy);

Instead of using ((MyService)AopContext.getCurrentProxy()).someMethod it is now possible to use this.proxy.someMethod and as a bonus not every but only an exclusive set of classes is effected.

So what have I learned from this expedition? Well, not so much about the dangers of proxied aop, the previously mentioned article already let me frown. And not so much about proxy awareness either, that seems to be some kind of wicketness by nature. But more about the possibility to define annotations and put the actual semantics of these annotations in seperate aspects. And whether that is evil or not, is probably again a matter of taste. But at least it is a funny and even elegant way of processing annotations using Spring AOP.

 

Attached Files:


— By Okke van 't Verlaat   Comments (0)   PermaLink

Menu


Sha256 mining

Blog Categories

Browse by Date
September 2006
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930 

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