• No results found

83Implementing pointcuts

In document InAction-AspectJ in Action 2nd Edition (Page 130-134)

Understanding the join point model

83Implementing pointcuts

all the instance and static methods defined in the Account class, whereas the latter picks up the instance methods in the class hierarchy of the Account class but none of the static methods.

ARGUMENT POINTCUTS

These pointcuts select join points based on the argument object’s runtime type of a join point. Objects considered as argument objects differ depending on the join point kind:

■ For method and constructor join points, the argument objects are the method and constructor arguments.

■ For exception-handler join points, the argument object is the handled exception.

■ For field write access join points, the argument object is the new value to be set. Argument-based pointcuts take the form args(Type or ObjectIdentifier, ..). Note that the selection is based on runtime type (similar to the this() or target() point- cuts) and not the declared type in program element.

Similar to execution object pointcuts, these pointcuts can be used to collect the con- text, but we’ll say more about this in chapter 4. Table 3.14 shows some examples of using argument pointcuts.

Table 3.14 Examples of argument pointcuts

Pointcut Description

args(Account,..,int) Any method or constructor join point where the first argument is of type Account and the last argument is of type int. This matches methods such as print(Object,float,int) as long as the first argument passes the instanceofAccount test.

args(RemoteException) Any join points with a single argument of type RemoteException. It matches a method or constructor taking a single

RemoteException argument, a field-write access setting a value of type RemoteException, or an exception handler of type

RemoteException.

Idiom: selecting join points only in subclasses

You can match all the join points only in subclasses of a type by using the this(Type) && !within(Type) idiom. You can also use the within(Type+) && !within(Type) pointcut, but it also selects join points in the nested classes in the subclasses.

Argument pointcuts at a glance

Selects—Join points matching argument types. Optionally, collects the matched

arguments.

Spring—Supported.

With Java 5, the use of annotations is proving to be a popular choice. Let’s see what AspectJ offers in this regard.

ANNOTATION-BASED POINTCUTS

AspectJ allows selection based on annotations carried by types, methods, and fields. Like the execution object and argument pointcuts, annotation-based pointcuts come in two forms: selection based on matching annotation types and collection of the matching annotation. For example, if MedicalRecord is annotated with @Sensitive, @this(Sensitive) selects all join points where this is of MedicalRecord type. If the @Sensitive annotation is marked as @Inherited (see the Java Language Specification for the semantics associated with the @Inherited meta annotation), it also matches join points where this instanceof MedicalRecord is true.

Table 3.15 summarizes these pointcuts and explains the version that performs only selection without collecting the matching annotation. We’ll discuss the version that collects the matching annotation in the next chapter.

Table 3.15 Annotation-based pointcuts in AspectJ

Pointcut Selection

@this(TypePattern or ObjectIdentifier)

Any join point where the this object’s type carries the annotation of the TypePattern type.

@target(TypePattern or ObjectIdentifier)

Any join point where the target object’s type carries the annotation of the TypePattern type.

@args(TypePattern or ObjectIdentifier, ..)

Any join point where the arguments’ type carries annotations of the

TypePattern.

@within(TypePattern or ObjectIdentifier)

Any join point in the lexical scope of a type that carries an annotation matching the specified TypePattern.

@withincode(TypePatter n or ObjectIdentifier)

Any join point where the matching program element (method or con- structor) carries an annotation matching the TypePattern.

@annotation(TypePatter n or ObjectIdentifier)

Any join point where the subject carries the specified annotation. For method, constructor, and advice-execution join points, the subject is the same as the program element. For field-access and exception- handler join points, the subject is the field or exception being accessed. For initialization and pre-initialization join points, the subject is the first called constructor matching the specified signature. For static initialization join points, the subject is the type being initialized.

Annotation based pointcuts at a glance

Selects—Join points based on annotations. Optionally, collects the matched

annotations.

Spring—Supports all except @this().

85 Summary

Note that the annotations used in a statically determinable pointcut in table 3.15 must have either class or runtime retention, whereas annotations used in the remaining pointcuts must have runtime retention.

So far, we’ve explored pointcuts that use join point signatures. AspectJ also offers a way to select based on arbitrary conditions.

CONDITIONAL CHECK POINTCUTS

This pointcut selects join points based on some conditional check at the join point. It takes the form of if(BooleanExpression). Table 3.16 shows some examples of using conditional check pointcuts.

The if() pointcut is often combined with other pointcuts to selectively apply dynamic crosscutting. For example, you can use execution(* *(..)) && if(debug) to apply a trace advice only if debug flag has been set to true. We’ll examine such usage in chapter 10.

3.7

Summary

The real innovation in AspectJ is the pointcut expression language; it’s powerful, expressive, and well thought out. Although we focused solely on AspectJ’s pointcut language, you’ll find that applying it to other AOP systems such as Spring and JBoss

AOP is easy—the concepts remain the same, even though different mechanisms are used. Furthermore, in Spring 2.0, you can use the AspectJ pointcut expressions directly without using the AspectJ weaver.

Table 3.16 Examples of conditional check pointcuts

Pointcut Description

if(debug) Any join point where the debug static field (in the defining aspect) is set to true.

if(System.currentTimeMillis() > triggerTime)

All the join points occurring after the current time has crossed the triggerTime value.

if(circle.getRadius() < 5) All the join points where the circle’s radius is less than 5. The circle object must be a context collected by the other parts of the pointcut or a static field in the defining aspect. See section 4.4.1 for details of the context-collection mechanism.

Conditional check pointcuts at a glance

Selects—Join points matching a condition Spring—Doesn’t support

AspectJ’s pointcut support offers many possibilities to facilitate writing good pointcuts:

You can write pointcuts exploiting program elements’ core components such as

name, defining types, and access modifier. If you use generics, you can specify those to further restrict in your selection criteria.

You can also use dynamic conditions such as runtime types involved at the join

point as well as the control flow that led to the execution of the join point.

■ You can also use annotations associated with the join points. During your initial exploration of AOP, annotation-based crosscutting will be particularly attractive. If the program elements of your interest carry annotations, it’s trivial to define a pointcut based on those annotations.

For some developers, AspectJ’s pointcut language may seem daunting at first. But in my experience, explaining pointcuts systematically—starting with simple pointcuts and then progressing to various signature patterns—invokes an “I see” expression without fail. When I give talks introducing AOP, I often show a few examples of simple pointcuts, explain the wildcards for a couple of minutes, and then ask attendees to tell me point- cuts for more complex selection. I am happy to report nearly 100% correct answers. The reason for such a good response is the consistent nature of the AspectJ language; when you understand the basics, complex patterns become obvious and intuitive.

Now that you know how to write type, method, and field signature patterns and how to utilize them in pointcuts to select the relevant join points, you’re ready to put them to good use. In the next chapter, we’ll discuss dynamic crosscutting, where addi- tional or augmentative behavior is associated with the selected join point.

87

Modifying behavior with

In document InAction-AspectJ in Action 2nd Edition (Page 130-134)