Quick Start Guide to Enterprise AOP with Aspectwerkz 2.0
Pages: 1, 2, 3

An Aside: Optimization Using StaticJoinPoint

AspectWerkz 2.0 supports the concept of a StaticJoinPoint, which unlike a normal JoinPoint, does not provide access to Runtime Type Information (RTTI). By eliminating RTTI, the weaver is able to optimize calls to the aspect, as it is no longer required to collect and make available the dynamic data for that JoinPoint.

For example, the logging aspect in the previous section logged the parameter values of each method call and therefore needed access to the RTTI. If we were not interested in logging the parameters, we could use a StaticJoinPoint to improve performance. The following aspect code and definition do just that:

public class LoggingIdiom {

    public Object trace(StaticJoinPoint jp, 

                               Loggable loggable) 

                               throws Throwable {

        CodeSignature cs = 

               (CodeSignature) jp.getSignature();

        loggable.getLog().enter(

               methodSignature(cs));

        Object result = jp.proceed();

        loggable.getLog().exit(

               exitTrace(jp, result));

        return result;

    }

}



...



<aspect class="com.tss.aop.LoggingIdiom">

  <pointcut name="p2" 

      expression="execution(* com.tss..*.*(..)) 

                        AND avoidTrace" />

  <advice name="trace(StaticJoinPoint jp, 

                  com.tss.aop.Loggable loggable)"

              type="around" 

  bind-to="p2 AND target(loggable)" />

</aspect>

Implementing a Profiling Aspect

Implementing the profiling aspect is much easier than implementing the logging aspect because the profiler can be called statically. This allows us to define the following simple aspect, without any need for mixins:

public Object profile(StaticJoinPoint jp) 

                   throws Throwable {

   Profiler.push(methodSig(jp));

   Object result = jp.proceed();

   Profiler.pop(methodSig(jp));

   return result;

}

This code is very straightforward. The aspect definition in aop.xml, however, is more interesting. We only want to profile those pointcuts specific to web requests, and so we use the cflow expression when selecting our pointcuts.

<aspect class="com.tss.aop.ProfilingIdiom">

  <pointcut name="p3" expression="cflow(

     execution(* com.tss.blog.web.

                 ApplicationServlet.service(..)))

     AND execution(* com.tss..*(..)) 

     AND avoidTrace"/> 

  <advice name="profile(StaticJoinPoint jp)" 

     type="around" bind-to="p3"/>

</aspect>

The cflow expression allows us to select only those pointcuts that are in the flow of control of the Tapestry pages. In other words, any call made within the execution of a web request will be profiled. This is a very powerful expression that allows us to solve the issue of avoiding profiling the initialization code; we are able to profile only those items that are of interest to us. In fact, we could have defined multiple profiler instances that have different behaviors based on what is being profiled. For example, web requests that take more than 5 seconds could trigger an error, while any scheduled background tasks that take longer than 10 seconds could also generate an error.

Conclusion

We have seen how applying AOP to a sample application makes the code base much easier to write, as well as more flexible and consistent. By implementing the logging and profiling concerns using separate aspects, we have solved all the problems outlined in the original application. Developers no longer need to be responsible for incorporating these concerns directly into their code. After reading this article and browsing the accompanying source code, it should take less than a day to incorporate these aspects into your code base. If this is done early enough in your project, you will realize a large cost savings, and developers on your team will thank you.

It is important to be pragmatic in the use of AOP and not apply it unnecessarily, especially in situations where an equally good non-AOP alternative already exists. That being said, if one is constrained to thinking without aspects for too long, implementation hacks like the tying of the profiler to the logger start to seem normal. When code starts to become tightly coupled simply because you get tired of typing the same code throughout all your classes, AOP can really help to simplify the code base.

The upcoming AspectJ 5 version will support all the features used in this article. Everything described will have a natural migration path to AspectJ 5. The first release should be available later this year.

References

David Teare is a graduate of The University of Western Ontario. He and his wife currently live in the Greater Toronto Area, where their company Teare Software Solutions is based