title: AspectJ_Example_1 —
Source files are here: AspectJEx1src.zip. If you need instructions on what do with these files, try here.
Predict the Output
This is the first of several exercise. If you’d like to get a feel for the general outline for each exercise, take a look here.
Code to Review
Examine the following 2 Java files. Your assignment is to predict the output based on these two files. —-
Main.java
MethodExecutionExample.java
Predict the output
Before continuing on, please predict the output from these two files.
title: AspectJEX1WhatIsHappening — PreviousNext
What Is Happening
Let’s take a step back. We just thought of ways this might have happened. When we did that, we were thinking in terms of “how” or implementation. Before we continue, let’s think of “what” is happening. You might think of this as “requirements” or “a use case”.
Assignment: Describe What
So your next assignment is to write down a description of what is happening. As you write your description, consider writing it without resorting to too much technological terminology. Please do so before continuing on to the next section.
title: AspectJEX1SoWhatIsHappening — PreviousNext
So What Is Happening?
Here are some descriptions I’ve heard some people mention:
- Every time we call a method, we print something before the method runs, the method runs, then we print something after the method runs.
- We intercept each method call and do something before and after it.
- As we execute a method, we use reflection to get the name of the method; we print “Entering” followed by the method name. We then execute the method, which always prints something. Finally, we print “Leaving” and the method name.
- We modify every method execution. Before and after the method execution we display the name of the method.
- …
title: AspectJEX1Explained — PreviousNext
Example 1 Explained
Capturing method execution is often what people first think of when considering AOP.
In this example, we intercept each method called on a class called MethodExecutionExample. Before each method call we print a message, we call the method and then print another message after returning from the method.
Aspect oriented Programming is about two things: Where, What.
What: What is it you want to do that is different from the normal program flow? Initially this is the easier part of the equation. It can get quite difficult but for this example it is trivial; print a message before and after a method execution.
Where: Where to you want to change the normal program flow. This is often the most difficult part of the equation. This is the skill to hone first. In this first example we simply pick out all public methods on a class. However, in my experience, the “where” is almost always as hard as or harder than the “what.”
Main.java is simply a driver and MethodExecutionExample.java is a simple class with some methods on it. In both cases, they are just Plain Old Java Objects (POJOs).
I did not show you three things:
- MethodExecutionAspect.java
- aop.xml
- The Java Virtual Machine is configured to give AspectJ a chance to modify classes as the VM loads them
MethodExecutionAspect.java
Interesting Lines
Lines | Description |
8 | This class is an AspectJ aspect class. It will need to be registered in the aop.xml file to take effect. |
10 | Define a pointcut. This is where the aspect applies. In this case it applies to execution of methods of any access level (the first *), in the class ex1.MethodExecutionExample, with any name (the second *) taking any parameters (..). |
11 | Give the pointcut a name, any name. The empty method has code placed into it that represents the pointcut. It is used later on line 14. |
14 | Around the exeuction of a pointcut do something. Around logic replaces the method. The around takes care of everything, including calling the original code. This around logic applies to all joinpoints captured by the pointcut called allMethods(). |
15 | This is the method that replaces the underlying method execution (all methods in the class ex1.MethodExecutionExample). It takes one parameter, a ProceedingJoinPoint, which is automatically provided by AspectJ. (More on what parameters can go here later.) |
19 | Call proceed() on “thisJoinPoint” to actually perform the original method execution. |
aop.xml
Interesting Lines
Lines | Description |
3 | Register ex1.MethodExecutionAspect as an apsect to apply to this VM |
6 | Only apply the registered aspects with classes whose package starts with ex1. |
Note, this file needs to be in a directory called META-INF in the classpath. Here’s an easy way to make this happen in eclipse:
- Create a folder called META-INF under a source directory
- Create a file called aop.xml in that folder
- Cut and paste the contents
title: AspectJVMConfigurationBlackMagic — PreviousNext
VM Configuration: Black Magic
This section describes the black magic that actually binds the MethodExecutionAspect class to the MethodExecutionAspect class. You can safely skip it but it is here just in case you are interested in what’s happening.
These examples work on a Java 5 VM. The Java 5 VM has a new command line option, javaagent. You can provide a so-called Java Agent Jar on the command line. When the VM starts up, it will look at the provided Jar file’s manifest. The manifest describes a class to hook into the Java Classloader. When there is a registered Java Agent, the following happens during class loading:
- The class loader finds a class
- The class loader retrieves the class’ byte codes into memory
- The class loader passes the byte codes to the Java Agent
- The Java Agent can make arbitrary changes to the byte codes
- The Java Agent returns the byte codes to the class loader
- The class loader then defines and initializes the class.
The Java Agent provided by AspectJ will modify classes based on the aop.xml file. Our aop.xml file mentions MethodExecutionExample. When the Classloader finds that class on disk, it retrieves it, passes it to the AspectJ Java Agent, which changes all of the methods to have calls into MethodExecutionAspect and then returns the modified class back to the class loader.
More Details
We’ve used several terms: joinpoint, pointcut, aspect.
- Joinpoint
- What is a joinpoint? It is a place in code that can be uniquely identified and somehow modified. Java VM’s execute bytecodes. A joinpoint, therefore, is a Java bytecode. Not all bytecodes can be uniquely identified. Not because they are not somehow look-up-able, but because the designers of AspectJ made a decision about where they will allow aspects to apply. This decision is the joinpoint model.
- Pointcut
- A pointcut is simply a collection of joinpoints. In our first example, the execution of all methods in a class called ex1.MethodExecutionExample. We’ll see more of these later. A pointcut is how you define what.
- Aspect
- An aspect is something that describes where to do what. In our first example, we used a joinpoint for where and what AspectJ refers to as advice for the what.
- Advice: Bad Name?
- Advice is the metaphor that AspectJ uses to describe what should happen when a pointcut is encountered. Ask your self this question, when given advice (or giving), it is always followed? Because it IS in AspectJ.
title: AspectJEX1ApplyYourself — PreviousNext
Apply Yourself
Here is a series of exercises you can try yourself to confirm what you’ve learned so far. Doing these assignments should really solidify your understanding of this first example.
Stateful Aspect
Track the number of times MethodExecutionAspect.reportMethodExecution() is called. Display this information as well as what it currently displays.
Challenge:
How many instances of MethodExecutionAspect are there? How can you tell? Make a theory. Test your theory by extending this assignment somehow.
Pointcut Changes
Change the pointcut to select only one particular method. Verify that your change worked.
Challenge: Use JUnit plus your knowledge from section 7.5.1 to programmatically test your pointcut.
Whole New Class
Create a simple Java Bean style class. Call it Address. Add the following attributes:
- addressLine1
- addressLine2
- city
- state
- zip
Add setters and getters for each of these attributes. Write a pointcut to select all of the methods starting with “set” and bind that pointcut to a SetMethodAspect class you create. Your SetMethodAspect.
Challenge:
Use string manipulation/regular expressions to convert the name of the method into the name of the attribute and print that instead.
Challenge:
Monopoly® Output Currently, the provided Monopoly® source code produces game output in the Game.play() method. Remove that output and instead write a method interceptor to display the same output. You’ll have to figure out which method to write and how to get access to the information you need.
Assessment:
Does doing this make sense? Is this a cross-cutting concern? How might you apply this kind of idea in a realistic situation?
Comments