Sunday 17 August 2008

AspectJ or Spring AOP?

Although Aspect Oriented Programming is a mature technology nowadays, it is not so widely used in enterprise applications, and this is, sometimes, due to the ignorance of the benefits of using it and the strength of its implementations or let’s say tools.

After being convinced to apply AOP, we must make a choice for the tool to use and the list of java frameworks as for almost all the areas is long. Fortunately this choice in our case is relatively easy (imho) because there are two predominant actors which are the most used and active ones and are AspectJ and Spring AOP. But even if I start by speaking about choices which traditionally means that I’ll compare the two solutions and make an exclusive choice (like for persistence, IoC…), I think that Spring AOP and AspectJ are two ‘opposite’/complimentary solutions that can coexist and interact without any problems. That's why in this particular case the real solution when applying AOP is to take in consideration the two tools and to make the choice based on the particular problem that we try to solve and its imposed context.

In fact the principal source of this opposition / complementarity resides in the nature of the two solutions; while aspectJ is a full AOP solution, based on class-weaving and is considered as a language on his own; Spring AOP is a relatively limited solution based on proxies and aiming to provide the Springframework the capacity to resolve with simplicity and transparency most commons enterprise application problems that are resolvable with AOP.

Being faced on a situation that we decide to resolve a particular problem or need with AOP, we must principally take in consideration three factors to determine which of the two tools, Spring AOP or AspectJ, to use:

  • The targets to be aspectized.
  • The type of pointcut needed by the aspect.
  • The invasiness of the solution.

So, firstly we must take on consideration the targets of our aspect, and this is due to two important facts that are the limitation of Spring AOP to act only on Spring beans and its incapacity to aspectise another aspect. Based on this it’s obvious that AspectJ is the solution in these cases.

The second consideration is to see what kind of pointcut our aspect needs; because Spring AOP can only be applied on method execution, whereas AspectJ can be applied on practically all types of possible pointcut (call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode,…). This can be seen as a big limitation for Spring AOP but in reality method execution based pointcuts are the most used ones in common enterprise application problematics; and this is simply because the major part of code fragments having meaningful (or important) business or technical logics are put into methods so it’s obvious that aspects are tied to these methods and are simply an externalisation and factorisation of what was put in these methods before using AOP.

The third consideration is our tolerance to the invasiveness of the adopted solution. Spring AOP being a pure java implementation presenting an xml based declarative solution (schema-based support) and offering a valuable @Aspect support, is perfectly transparent. On the other side, being a class weaving based tool, AspectJ is relatively invasive. In fact if we choose the compile-time solution we must use the AspectJ specific compiler to weave the target application; even if this compiler has made many evolutions to be able of weaving source code as well as already compiled classes (or aspects - for aspect libraries) (this is also said post-compile weaving or binary weaving) even in a packaged form (for third party libraries or legacy applications) and its performance was remarkably optimized. Personally, and based on my own experience I think that even if transparency is an important consideration, its not so prohibitive to use compile time weaving, because after all, this consecutive ‘pollution’ is localized in the build relative part and not propagated in our code; and tools like maven or Ant offers a big support for these needs; then I think that independently of what tool or support to use, the most important here, and more generally for all problems of this type, is the good modularisation of our application. AspectJ presents also an alternative to compile-time weaving, which is the Load-Time weaving; this feature is more transparent than the traditional one and can be enabled in different ways, but it still an exotic solution that must gain more maturity to be used as widely as compile-time weaving.

There are also some miscellaneous considerations that can be important in some situations. As for other factors of discrimination these particularities are imposed principally by the natures of the two tools. In fact due to its proxy based implementation Spring AOP can presents some unexpected behaviour when faced to the use of the ‘this’ java keyword in the target method which can be a serious limitation when consider to use the developed aspects on legacy code or on third party libraries. Always for the same reasons, Spring AOP aspects can be instantiated only as singletons with the schema based support; and also as with the ‘perthis’ and ‘pertarget’ AspectJ’s instantiation model when using the @Aspect way; while the ‘percflow’ and ‘percflowbelow’ instantiation models are not yet supported. Then, there are performance issues; personally I never find a case where this issue was prohibitive for the use of AOP, and I’ll limit myself to mention the AWBench for those who want to make more investigations on performance.

Finally, and as a conclusion of what was mentioned above, I think that the best approach to take when we are faced to the problem consisting in to choosing what AOP tool to use between these two solutions, is to see firstly if we are in the applicability scope of Spring AOP (a spring bean as a target and a method execution as a pointcut); based on this we obviously must choose AspectJ in the case where we are out of this scope, else, I recommend using Spring AOP with the @Aspect support, which gives us the possibility of changing our initial choice and to use AspectJ if our needs evolutes and can’t be satisfied by Spring AOP.

No comments:

Post a Comment