Fall 2002 Programming Language Seminar:
Aspect-Oriented Programming with AspectJ

Back to main course page

[ Washington University in St Louis ]
Department of Computer Science

Course Notes: 28 August 2002

Welcoming comments

Prerequisite: Java programming is very helpful, but C++ programmers can generally pick up Java fairly easy

There will be no exams or quizzes given in-class (and no substantial exam outside of class). The work of this class primarily will be focussed on the design and implementation of aspect-oriented AspectJ programs, with some smaller projects at the beginning and one or two larger assignments toward the middle or end of the semester. The course will chiefly deal with AspectJ, although there may be some mention of other systems for achieving similar ends as AspectJ, as well as other proposals aiming to meet the same benefits as Aspect-Oriented Programming.

Introduction to Aspect-Oriented Programming

Aspect-Oriented systems fall under the category of Advanced Separation of Concerns (ASoC). ASoC aims to allow the modular decomposition of software concerns that cross-cut the nature of an Object-Oriented program.

Concerns come in two general flavors, non-functional (or systemic) and functional. Non-functional concerns have to do with some aspect of the overall correctness of a program (for example: real-time requirements, thread synchronization, transaction semantics, caching/prefetching, memory management concerns, security, scheduling), while functional concerns correlate (roughly) to features of a program (for example: logging, encryption, additional supported network protocols) that may be included or excluded for a particular compile (or run) of the program. Note that functional concerns are somewhat like plugins in software -- a modular piece of code that is plugged in to achieve additional functionality. In software that supports plugins, however, the base code must acknowledge the existence of a plugin system and make calls out to it. With ASoC, the idea is to keep the core code and the plugins (and even the plugin system itself) completely independent.

Further, functional concerns can be configurational. In an Object-Oriented system, you may describe a particular organization's personnel hierarchy with an XML document, then parse and read it into an object at runtime. This object then typically either (1) resides as a Singleton, where it is accessed by all objects, or (2) is passed as an argument to the methods that require it as part of their computation. Unfortunately, this solution requires other objects to manipulate the personnel-hierarchy object in their code in order to carry out whatever requirements it asserts. This leads to an integration, rather than separation, of concerns. A truly modular approach would allow the configuration object independently to impose its requirements.

Ideally, then, all of our classes are totally abstract and totally independent. This isn't entirely possible, however (if there were absolutely no inter-object relationships, they couldn't form a cohesive program), but the points where code between different concerns gets tangled can be smoothed over if a separate aspect defines such relationships.

(Side note: This idea of a complete separation is at the core of Generative Programming, in which reusable components are built separately and then a "configuration" (in some form) is injected into the system to make them all behave together flexibly.)

Quantification and Obliviousness. Robert Filman and Daniel Friedman have observed that the key distinguishing feature of Aspect-Oriented Programming is that they exhibit quantification and obliviousness [Filman and Friedman, Aspect-Oriented Programming is Quantification and Obliviousness, available in PDF]. Quantification refers to the idea that one piece of code explicitly affects various other places in completely different sections of code; obliviousness (sometimes termed implicit invocation) to the fact that the receiving code can be (and ideally is) completely oblivious to the quantification that applies to it.

A Basic Starting Point for AspectJ

For a first AspectJ program, let's take a look at Hello World:

public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello World!");
  }
}

That's it. This is a complete AspectJ program (as well as a complete Java program). All Java programs are AspectJ programs. But this isn't very interesting, so let's add an aspect:

public aspect A {
  // declare a pointcut
  pointcut mainExecutes() :
    execution(public static void main(String[]));
  // define some advice on the pointcut
  before() : mainExecutes() {
    org.somewhere.subsystem.init();
  }
}

The purpose of this aspect is to initialize some subsystem before the main() method executes. First, we declare an AspectJ pointcut, and name it mainExecutes(). This declaration binds the name mainExecutes to executions of the provided method name.

Some Definitions:

In AspectJ, join points are points in the execution of a program. (Other aspect proposals may define other sorts of join points.)

But why separate this at all? Wouldn't copying all the subsystem initialization stuff into main() be easier? Perhaps in some cases, yes. But if the subsystem initialization is a completely separate concern than that of the main program, or if you have multiple subsystem initializations to perform, it may be worth considering the modularity afforded by a solution like the above. Next week we'll examine more interesting examples.

Aspects may contain many pointcuts and advice definitions, and multiple aspects can affect the same join point.

This gives you enough to complete Homework 1, the main purpose of which is to ensure that you can get AspectJ working.


Please contact me at mdeters@cse.wustl.edu if you have any questions regarding these notes.

Help on setting up AspectJ
Back to AspectJ Seminar course calendar


Morgan Deters / About me / OpenPGP Public Key / 02 Jan 2006

This page is certified valid HTML 4.01!  This page refers to certified valid CSS!  I support the AnyBrowser campaign