ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button
  Introduction to Aspect-Oriented Programming
Subject:   crosscutting, not static+ or just interception
Date:   2004-01-16 03:30:39
From:   anonymous2
I think AspectWerkz has a lot to offer and am grateful for your gentle walkthrough of their form of aspects. But I think you've misconceived AOP and AspectJ.

The raison d'etre of AOP is not "dynamically modifying static structure." No AOP modifies Java dynamically, and any changes to implement advice have to preserve the static structure. However, people do take advice, pointcuts, and join points as essential to AOP, and it is valuable that you laid out an example of these.
(fyi, when you define "Point-cut", you're describing a join point. A pointcut is the crosscutting specification that enables you to pick out points in the program at which behavior can be joined - so-called join points. Here the method-execution itself is a join point and the pointcut is the pattern that matches the method signature.)

It's not true that using AspectJ means you have to switch compilers or IDE's. The only difference is that the others hide the weaver invocation by invoking it programmatically at class load time. AspectJ does bytecode weaving just like AspectWerkz and JBoss (or vice-versa), and all can be run at build-time or class-load time. So you can compile your code with javac, compile your aspects with AspectJ, and weave them together at the end.

(Also, you say that no one's using javac directly any more, they're all using Ant. To use the AspectJ compiler requires only setting Ant's ${build.compiler} property, so AspectJ should be easier to integrate into anyone's build system than having to deploy under a particular version of JBoss or to mess with system class loader reweaving as AspectWerkz does.)

Using XML to state the least possible and invoking the weaver implicitly makes it easy to get started, but both actually make it harder to do anything useful. Running the weave explicitly means you can get error messages when you make mistakes like '* exampl.*Servlet.doGet(..)' Also, the compiler is able to do the static analysis necessary to preserve type- and exception-safety and to optimize away the expensive reflective lookups. By contrast, these frameworks tend to require downcasts and wrap checked exceptions in runtime exceptions, making errors more likely and harder to find. For this reason, AspectJ started with a compiler and doesn't offer examples of load-time weaving, because people are just more productive that way.

I agree with your implicit point, however, that the AOP part should only be doing its job -- in this case, connecting servlet calls with persistence. Here's your XML and Java code as an AspectJ aspect:

aspect PersistServletCalls {
after(HttpServletRequest request)
returning : args(request, ..)
&& execution(* Servlet+.doGet(
HttpServletRequest,..) {
} }

It just hands things over to the persistence thingy which is responsible for deciding dynamically what to persist and how. (If you really want Person-specific persistence that doesn't need a dynamic check, you could specify that instead whereever Person is passed around or sends messages of its own.)

I would note that it's more obviously safe. We know without looking at the code body that it only runs after returning normally, so it doesn't affect the underlying join point. The code is safer too. We don't have to downcast JoinPoint or HttpServletRequest or know where it is in the parameters. You *can* do around advice in AspectJ, but you don't if there's a more precise form available.

Similarly, I suspect AspectWerkz has superclasses for other kinds of advice, and might in off-line mode provide some of the error messages that AspectJ does; I don't mean to say that it can't (since I don't know), but that what makes it, or other AOP things, interesting is the extent to which they offer a safe and sensible way of handling crosscutting concerns..

I guess my point is that we really have to focus on crosscutting to introduce AOP. A reflective interception mechanism is to AOP what a stack frame is to OO: it provides part of the machinery, but almost none of the guarantees or 'ilities that make one OO language better than another or different from procedural languages.

1 to 1 of 1
1 to 1 of 1