next up previous
Next: Advice grouping Up: Aspects and Polymorphism in Previous: Run-time pointcut designators and

Late Binding of Advice

An interesting extension is introducing polymorphism in connection with advice. The advice language element can be extended so that the advice which is possibly applied at a given point in the execution of the program is chosen dynamically from a set of applicable advice declarations, similarly to dynamic dispatch where one method implementation is chosen from a set of applicable ones. We use the term late binding of advice to denote such a mechanism.

Consider the IncrTracking aspect in Listing IncrTracking.java.

(Listing IncrTracking.java)

aspect IncrTracking {
  after(FigureElement fe): target(fe) 
    && call(void FigureElement.incrXY(int,int)) {
    System.out.println("IncrTracking: "
      + "Moving the figure element " + fe);
  }
  after(Point p): target(p) 
    && call(void Point.incrXY(int,int)) {
    System.out.println("IncrTracking: "
      + "Moving the point at (" 
      + p.getX() + "," + p.getY() + ")");
  }
}
Today, the two advice declarations in IncrTracking, and indeed any two advice declarations, would be invoked independently of each other. For each point in the execution of the program where an advice might be enabled it is determined whether or not that advice should be invoked, without considering any other advice. In fact, putting the two advice declarations in two separate aspects

(Listings IncrTrackingFigureElement.java and [*]) would give the same behavior as the code in Listing IncrTracking.java. They only differ in the identity and number of aspect instances, which is immaterial for stateless aspects, and the ordering of advice code execution, which can be controlled using aspect domination: [*]

(Listing IncrTrackingFigureElement.java)

aspect IncrTrackingFigureElement {
  after(FigureElement fe): target(fe) 
    && call(void FigureElement.incrXY(int,int)) {
    System.out.println("IncrTrackingFigureElement:"
      + " Moving the figure element " + fe);
  }
}

(Listing IncrTrackingPoint.java)

aspect IncrTrackingPoint 
  dominates IncrTrackingFigureElement {
  after(Point p): target(p) 
    && call(void Point.incrXY(int,int)) {
    System.out.println("IncrTrackingPoint: "
      + "Moving the point at (" 
      + p.getX() + "," + p.getY() + ")");
  }
}
As a result we might invoke zero, one, or two of the above advice declarations. This is true both when the answer is known statically, and also when a dynamic check is required.

To avoid the case of invoking both of the above advice declarations, it is possible to use around-advice without calling proceed

(Listings IncrTrackingFigureElement2 and IncrTrackingPoint2)

(Listing IncrTrackingFigureElement2.java)

aspect IncrTrackingFigureElement2 {
  void around(FigureElement fe): target(fe) 
    && call(void FigureElement.incrXY(int,int)) {
    System.out.println("IncrTrackingFigureElement2"
      + ": Moving the figure element " + fe);
    // do not invoke proceed(fe);
  }
}

(Listing IncrTrackingPoint2.java)

aspect IncrTrackingPoint2
  dominates IncrTrackingFigureElement2 {
  void around(Point p): target(p) 
    && call(void Point.incrXY(int,int)) {
    System.out.println("IncrTrackingPoint2: "
      + "Moving the point at (" 
      + p.getX() + "," + p.getY() + ")");
    // do not invoke proceed(p);
  }
}
By doing so, the around-advice that is invoked first will prevent the other around-advice from being invoked. This is perhaps closer to late binding of advice, and can be used in a Visitor [12] design pattern style [24]. However, it is not quite the same as late binding, because it does not cover kinds of advice other than around-advice; it does not allow the base method to be invoked; and it lets one advice override all other advice declarations including, e.g., an unrelated before-advice with different arguments. The latter demonstrates the need for advice grouping.



Subsections
next up previous
Next: Advice grouping Up: Aspects and Polymorphism in Previous: Run-time pointcut designators and
David H. Lorenz 2003-01-15