■■ Signatures
■■ Patterns
■■ Reflections
■■ Join point examples
The Dynamic Join Point Model
To illustrate what join points are and how they are used in writing AspectJ programs for crosscutting a component application, let’s use a simple component class. We use this same class throughout this chapter to provide join point
AspectJ Join Points
C H A P T E R
5
examples. Figure 5.1 shows a class hierarchy that implements a hierarchy for products. The Product class is a high-level class containing attributes for the product price. The DVD class represents a DVD and extends Product. The Boxset class extends Product and encapsulates some number of DVD products. Each class has setter and getter methods, and the DVD/Boxset class has a constructor. Listing 5.1 contains the code for the various classes represented in Figure 5.1. Of particular importance are the count and location attributes in both DVD and Boxset. These attributes and associated methods are used to track product. In themselves, these attributes and methods don’t have anything to do with the fun- damental DVD and Boxset product. They represent a concern, inventory han- dling, outside the scope of either class. The concern is crosscutting the core implementation of the classes. As we all know, there are always several ways to code a problem. Some argue that inventory handling should be a primary concern and thus coded with the component language and potentially as part of the Prod- uct class. However, I contend that a product doesn’t contain inventory informa- tion. A product is an entity that contains attributes such as price, title, and size.
AspectJ Join Points
54 Product double price setPrice (double) DVD String title int count String location public DVD(String) public void setCount(int) public int getCount()
private void setLocation(String) private String getLocation() public void setStats(String int)
Boxset int totalCount Vector includedDvds String location String title public Boxset(String) public void add(DVD) private void setLocation(String) private String getLocation() 1 *
Figure 5.1 Our sample class hierarchy.
public class Product {
private double price;
The Dynamic Join Point Model 55
public void setPrice(double inPrice) { price = inPrice;
} }
public class DVD extends Product {
private String title; private int count; private String location;
public DVD(String inTitle) { title = inTitle;
}
public void setCount(int inCount) { count = inCount;
}
public int getCount() { return count;
}
private void setLocation(String inLocation) { location = inLocation;
}
private String getLocation() { return location;
}
public void setStats(String inLocation, int inCount) { setLocation(inLocation);
setCount(inCount); }
}
import java.util.Vector;
public class Boxset extends Product { private int totalCount;
private Vector includedDvds; private String location; private String title;
public Boxset(String inTitle) {
AspectJ Join Points
56
includedDvds = new Vector(); totalCount = 0;
title = inTitle; }
public void add(DVD inDvd) { inDvd.setStats(location, 1); includedDvds.add(inDvd); totalCount++;
}
public void setLocation(String inLocation) { location = inLocation;
}
public String getLocation() { return location;
} }
Listing 5.1 Our sample class code. (continued)
We use the defined classes in the following snippet of code to show how the join points are detailed throughout the DVD class:
DVD dvd1 = new DVD("Star Wars");
DVD dvd2 = new DVD("Empire Strikes Back"); DVD dvd3 = new DVD("Return of the Jedi"); Boxset set = new Boxset("StarWars Trilogy"); set.setTitle("Great DVD Store");
set.add(dvd1); set.add(dvd2); set.add(dvd3);
The code begins with the creation of three DVD objects and one Boxset object. All the objects have their title attribute set through the constructor of each indi- vidual object. Figure 5.2 illustrates the creation of all the objects along with an execution path for the creation of the Boxset object. The join points for the creation of the Boxset object are as follows:
1. A constructor call join point for the call made to create the Boxset object 2. A constructor call reception (not a join point in AspectJ but noted) 3. A constructor execution join point for when the code within the construc-
tor is invoked
4. A constructor call for the creation of the Vector object within the Boxset constructor
5. A constructor call reception join point for the creation of the Vector object 6. A constructor execution join point for the Vector object
7. A field set join point for setting the totalCount attribute 8. A field set join point for setting the title attribute
Although we haven’t shown them here, the Vector object could have join points defined against it as well. Just because we don’t have the source code doesn’t mean we cannot match the methods/constructors and other join points with the object.
The Dynamic Join Point Model 57
4 3 2 1 5 6 7 8
Boxset boxset = new Boxset();
Figure 5.2 The execution path for creating the Boxset object.
The point that should be most clear from Figure 5.2 is the number of join points available in the execution of just a single line of code. At just about any key location (except for the individual statements), a join point is available. In Figure 5.3, we see the execution path for a line of code in the previous exam- ple, set.add(dvd1);, which adds a whole set of additional join points. The points are as follows:
1. A method call join point for the call to the add() method
2. A method call reception join point for the beginning of code execution within the add() method
3. A method execution join point
4. A method call reception join point for the call to the DVD setStats() method
5. A method execution join point for the beginning of code execution with the setStats() method
6. A method call join point for the call to the DVD setLocation() method call 7. A method execution join point for the beginning of code execution within
the setLocation() method call
8. A field set join point for setting the location attribute
9. A method call reception join point for after code execution in the setLocation() method call
10. A method execution join point for the call to the DVD setCount() method call
11. A field set join point for setting the count attribute
12. A method call join point for the call to the add() method of the Vector 13. A field set join point for the totalCount join point.
AspectJ Join Points
58 12 4 5 9 1 10 7 13 3 2 6 8 11
Figure 5.3 The execution call path for the add() method.
We used some of the specific join points made available in AspectJ in our exe- cution call paths. Note that not all available join points are used in a typical application, nor are all types of designators used. In the next section, we exam- ine the specific join points available in AspectJ.
AspectJ Join Points
The current version of AspectJ, 1.1, defines a host of join points available to be triggered. These join points are:
TEAM
FLY
Method call—A method call join point is defined when any method call is made by an object or a static method if no object is defined, as in the case of the main() method. This join point is defined within the calling object or application. Consider this code example based on the classes we defined earlier:
public static void main(String args[]) { Boxset set = new Boxset("StarWars Trilogy"); set.setTitle("Great DVD Store");
}
A join point set on the set.setTitle(“Great DVD Store”); method is triggered in the context of main() as opposed to the Boxset object. Consider the fol- lowing pointcut:
pointcut TitleChange() : call(public void setTitle(String)) && target(Boxset);
This pointcut defines a group containing a join point defined by a call to the setTitle(String); method. Any place in the code where a call is made to set- Title(String), the pointcut is triggered as long as the target of the call is a Boxset object.
Constructor call—A constructor call join point is defined when a con- structor is called during the creation of a new object. This join point is defined within the calling object or application if no object is defined. Con- sider this code example:
public static void main(String args[]) { Boxset set = new Boxset("StarWars Trilogy"); }
A join point set on the new statement triggers a constructor call join point based on the main() method. Here’s a pointcut for this example:
pointcut constructSet() : initialization(Boxset.new(String));
Method call execution—A method call execution join point is defined
when a method is called on an object and control transfers to the method. The join point is triggered based on the object receiving the method call before any of the code within the method is executed. It is assured that the join point will be triggered upon transfer of execution to the method just before the method code begins to process. For example, consider the fol- lowing code example:
public static void main(String args[]) { Boxset set = new Boxset("StarWars Trilogy"); set.setTitle("Great DVD Store");
}
In this example, a method call execution join point could be defined on the setTitle(String) method. When the call is made to the method through the
set object, the join point will be triggered based on the set object just before the setTitle() method is to be executed. A corresponding pointcut would be
pointcut titleReception() :
execution(public void setTitle(String));
Constructor call execution—A constructor call reception join point is
the same as the method call reception join point except we are dealing with constructors. The join point is triggered before the constructor code starts to execute.
Field get—A field get join point is defined when an attribute associated with an object is read. In our example, a call to the method getLocation() causes a field get join point to be triggered because the attribute is
accessed, not because of the actual getLocation() method. A corresponding pointcut would be
Pointcut locationGet() : get(public String DVD.location);
Field set—A field set join point is defined when an attribute associated with an object is written. In our example, a call to the method
setLocation(String) causes a field set join point to be triggered. A corre- sponding point would be
Pointcut locationSet() : set(public String DVD.location);
Exception handler execution—An exception handler execution join
point is defined when an exception handler is executed.
Class initialization—A class initialization join point is defined when any static initializers are executed for a specific class. If there are no static ini- tializers, there will be no join points.
Object initialization—An object initialization join point is defined when a dynamic initializer is executed for a class. This join point is triggered after a call to an object’s parent constructor and just before the return of the object’s constructor.