Section 6.5. Writing a Logging Aspect Using AspectJ


6.5. Writing a Logging Aspect Using AspectJ

The first thing to do is to write the Aspect you're going to apply to the project's code which will run the Logifier plug-in. The goal here is not to do a tutorial on AspectJ (for this, see http://www.eclipse.org/aspectj/).

6.5.1. How do I do that?

Without further ado, here's the first part of the Aspect you'll develop:

import org.aspectj.lang.reflect.*; import org.aspectj.lang.*;    public aspect Logging {     /**      * All public methods that have parameters.      */     pointcut publicMethodsWithParameterCalls( ) :         !execution(public * *( ))         && execution(public * *(..));        /**      * All public static methods that have parameters.      */     pointcut publicStaticMethodsWithParameterCalls( ) :         !execution(public static * *( ))         && execution(public static * *(..));  [...]

AspectJ extends the Java language and adds new keywordsamong them aspect and pointcut. You can see here that the aspect keyword declares an Aspect (in lieu of the class keyword), and pointcut declares an identifier matching some code. AspectJ has a little language to express how to match portions of code. For example, the publicMethodsWithParameterCalls( ) PointCut Definition (PCD) translates to "whenever the code does not execute a public method with no parameter AND whenever the code executes a public method with parameters (signified by the .. notation, which means zero or more parameters)." Confused? In English, the previous logic-speak can be translated to: execution of all public methods that have parameters.

The next step is to tell the Logging Aspect what to do when the PointCuts are matched. You do this by using yet another new keyword, around( ):

    /**      * Log all entries and exits of non-static methods that have no return      * values.      */     Object around( ) :         publicMethodsWithParameterCalls( )         && !publicStaticMethodsWithParameterCalls( )     {         // Log the entry         System.out.println('<' + getFullSignature(thisJoinPoint));            long t1 = System.currentTimeMillis( );             // Execute the method         final Object result = proceed( );            long t2 = System.currentTimeMillis( );            // Log the exit         String output = '>' + thisJoinPoint.getSignature( ).getName( );         if (result != null)         {             output = output + " = [" + result + ']';         }         System.out.println(output + " (" + (t2-t1) + "ms)");            return result;     } [...]

The around keyword is called advice in AspectJ terminology, and it tells the Aspect what to do when a PCD is matched. There are three main types of advice: before(), after( ), and around( ). before( ) is executed before the matching PCD, after( ) is executed after the matching PCD, and around( ) is executed around your PCD. In the around( ) advice used earlier, proceed( ) is used to execute the method matched by the PCD, and to capture the method's return value.

So, here you're saying "run this piece of code whenever you find execution of public methods with parameters that are not static methods." Why do you want this? This is just an example, and in practice we've found that logging methods with no parameters generates too many logs and is not too useful. In this example, static methods are excluded because the special thisJoinPoint variable does not exist for static methods, and to address static methods you would need to write this advice differently (look at the source code for the full example containing support for static calls).

The rest of the code is standard Java code that prints the signature of the wrapped method using getFullSignature( ). If you are interested in seeing the output generated by getFullSignature( ), take a look at the same source code on http://www.mavenbook.org. As a little bonus, the previous code also computes the time it has taken to execute the wrapped method, thus playing the role of a very lightweight profiling tool.

So, now that you've created a simple Aspect, combine this with your knowledge of Maven plug-ins and create a plug-in to apply this Aspect to any Maven project.



Maven. A Developer's Notebook
Maven: A Developers Notebook (Developers Notebooks)
ISBN: 0596007507
EAN: 2147483647
Year: 2003
Pages: 125

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net