| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Join Points and Pointcuts</title><link rel="stylesheet" href="aspectj-docs.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.44"><link rel="home" href="index.html" title="The AspectJTM Programming Guide"><link rel="up" href="language.html" title="Chapter 2. The AspectJ Language"><link rel="previous" href="language-anatomy.html" title="The Anatomy of an Aspect"><link rel="next" href="language-advice.html" title="Advice"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Join Points and Pointcuts</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="language-anatomy.html">Prev</a> </td><th width="60%" align="center">Chapter 2. The AspectJ Language</th><td width="20%" align="right"> <a accesskey="n" href="language-advice.html">Next</a></td></tr></table><hr></div><div class="sect1"><a name="language-joinPoints"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-joinPoints"></a>Join Points and Pointcuts</h2></div></div><p> |
| Consider the following Java class: |
| </p><pre class="programlisting"> |
| class Point { |
| private int x, y; |
| |
| Point(int x, int y) { this.x = x; this.y = y; } |
| |
| void setX(int x) { this.x = x; } |
| void setY(int y) { this.y = y; } |
| |
| int getX() { return x; } |
| int getY() { return y; } |
| } |
| </pre><p> |
| In order to get an intuitive understanding of AspectJ's join points |
| and pointcuts, let's go back to some of the basic principles of |
| Java. Consider the following a method declaration in class Point: |
| </p><pre class="programlisting"> |
| void setX(int x) { this.x = x; } |
| </pre><p> |
| This piece of program says that that when method named |
| <tt>setX</tt> with an <tt>int</tt> argument |
| called on an object of type <tt>Point</tt>, then the method |
| body <tt>{ this.x = x; }</tt> is executed. Similarly, the |
| constructor of the class states that when an object of type |
| <tt>Point</tt> is instantiated through a constructor with |
| two <tt>int</tt> arguments, then the constructor body |
| <tt>{ this.x = x; this.y = y; }</tt> is executed. |
| </p><p> |
| One pattern that emerges from these descriptions is |
| |
| <blockquote class="blockquote"> |
| When something happens, then something gets executed. |
| </blockquote> |
| |
| In object-oriented programs, there are several kinds of "things that |
| happen" that are determined by the language. We call these the join |
| points of Java. Join points consist of things like method calls, |
| method executions, object instantiations, constructor executions, |
| field references and handler executions. (See the <a href="quick.html">AspectJ Quick Reference</a> for a complete listing.) |
| </p><p> |
| Pointcuts pick out these join points. For example, the pointcut |
| </p><pre class="programlisting"> |
| pointcut setter(): target(Point) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| picks out each call to <tt>setX(int)</tt> or |
| <tt>setY(int)</tt> when called on an instance of |
| <tt>Point</tt>. Here's another example: |
| </p><pre class="programlisting"> |
| pointcut ioHandler(): within(MyClass) && handler(IOException); |
| </pre><p> |
| This pointcut picks out each the join point when exceptions of type |
| <tt>IOException</tt> are handled inside the code defined by |
| class <tt>MyClass</tt>. |
| </p><p> |
| Pointcut definitions consist of a left-hand side and a right-hand side, |
| separated by a colon. The left-hand side consists of the pointcut name |
| and the pointcut parameters (i.e. the data available when the events |
| happen). The right-hand side consists of the pointcut itself. |
| </p><div class="sect2"><a name="some-example-pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="some-example-pointcuts"></a>Some Example Pointcuts</h3></div></div><p> |
| Here are examples of pointcuts picking out |
| </p><div class="variablelist"><dl><dt><a name="d0e1024"></a><span class="term">when a particular method body executes</span></dt><dd><p><a name="d0e1027"></a> |
| <tt>execution(void Point.setX(int))</tt> |
| </p></dd><dt><a name="d0e1033"></a><span class="term">when a method is called</span></dt><dd><p><a name="d0e1036"></a> |
| <tt>call(void Point.setX(int))</tt> |
| </p></dd><dt><a name="d0e1042"></a><span class="term">when an exception handler executes</span></dt><dd><p><a name="d0e1045"></a> |
| <tt>handler(ArrayOutOfBoundsException)</tt> |
| </p></dd><dt><a name="d0e1051"></a><span class="term"> |
| when the object currently executing |
| (i.e. <tt>this</tt>) is of type |
| <tt>SomeType</tt> |
| </span></dt><dd><p><a name="d0e1060"></a> |
| <tt>this(SomeType)</tt> |
| </p></dd><dt><a name="d0e1066"></a><span class="term"> |
| when the target object is of type <tt>SomeType</tt> |
| </span></dt><dd><p><a name="d0e1072"></a> |
| <tt>target(SomeType)</tt> |
| </p></dd><dt><a name="d0e1078"></a><span class="term"> |
| when the executing code belongs to |
| class <tt>MyClass</tt> |
| </span></dt><dd><p><a name="d0e1084"></a> |
| <tt>within(MyClass)</tt> |
| </p></dd><dt><a name="d0e1090"></a><span class="term"> |
| when the join point is in the control flow of a call to a |
| <tt>Test</tt>'s no-argument <tt>main</tt> |
| method |
| </span></dt><dd><p><a name="d0e1099"></a> |
| <tt>cflow(call(void Test.main()))</tt> |
| </p></dd></dl></div><p> |
| Pointcuts compose through the operations <tt>or</tt> |
| ("<tt>||</tt>"), <tt>and</tt> |
| ("<tt>&&</tt>") and <tt>not</tt> |
| ("<tt>!</tt>"). |
| </p><div class="itemizedlist"><ul><li><p><a name="d0e1126"></a> |
| It is possible to use wildcards. So |
| |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1130"></a> |
| <tt>execution(* *(..))</tt> |
| </p></li><li><p><a name="d0e1136"></a> |
| <tt>call(* set(..))</tt> |
| </p></li></ol></div> |
| |
| means (1) the execution of any method regardless of return or |
| parameter types, and (2) the call to any method named |
| <tt>set</tt> regardless of return or parameter types |
| -- in case of overloading there may be more than one such |
| <tt>set</tt> method; this pointcut picks out calls to |
| all of them. |
| </p></li><li><p><a name="d0e1149"></a> |
| You can select elements based on types. For example, |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1153"></a> |
| <tt>execution(int *())</tt> |
| </p></li><li><p><a name="d0e1159"></a> |
| <tt>call(* setY(long))</tt> |
| </p></li><li><p><a name="d0e1165"></a> |
| <tt>call(* Point.setY(int))</tt> |
| </p></li><li><p><a name="d0e1171"></a> |
| <tt>call(*.new(int, int))</tt> |
| </p></li></ol></div> |
| |
| means (1) the execution of any method with no parameters that |
| returns an <tt>int</tt>, (2) the call to any |
| <tt>setY</tt> method that takes a |
| <tt>long</tt> as an argument, regardless of return |
| type or declaring type, (3) the call to any of |
| <tt>Point</tt>'s <tt>setY</tt> methods that |
| take an <tt>int</tt> as an argument, regardless of |
| return type, and (4) the call to any classes' constructor, so |
| long as it takes exactly two <tt>int</tt>s as |
| arguments. |
| </p></li><li><p><a name="d0e1199"></a> |
| You can compose pointcuts. For example, |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1203"></a> |
| <tt>target(Point) && call(int *())</tt> |
| </p></li><li><p><a name="d0e1209"></a> |
| <tt>call(* *(..)) && (within(Line) || within(Point))</tt> |
| </p></li><li><p><a name="d0e1215"></a> |
| <tt>within(*) && execution(*.new(int))</tt> |
| </p></li><li><p><a name="d0e1221"></a> |
| <tt> |
| !this(Point) && call(int *(..)) |
| </tt> |
| </p></li></ol></div> |
| |
| means (1) any call to an <tt>int</tt> method with no |
| arguments on an instance of <tt>Point</tt>, |
| regardless of its name, (2) any call to any method where the |
| call is made from the code in <tt>Point</tt>'s or |
| <tt>Line</tt>'s type declaration, (3) the execution of |
| any constructor taking exactly one <tt>int</tt> |
| argument, regardless of where the call is made from, and |
| (4) any method call to an <tt>int</tt> method when |
| the executing object is any type except <tt>Point</tt>. |
| </p></li><li><p><a name="d0e1249"></a> |
| You can select methods and constructors based on their |
| modifiers and on negations of modifiers. For example, you can |
| say: |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1253"></a> |
| <tt>call(public * *(..))</tt> |
| </p></li><li><p><a name="d0e1259"></a> |
| <tt>execution(!static * *(..))</tt> |
| </p></li><li><p><a name="d0e1265"></a> |
| <tt> execution(public !static * *(..))</tt> |
| </p></li></ol></div> |
| which means (1) any call to a public method, (2) any |
| execution of a non-static method, and (3) any execution of a |
| public, non-static method. |
| </p></li><li><p><a name="d0e1272"></a> |
| Pointcuts can also deal with interfaces. For example, given the |
| interface </p><pre class="programlisting"> |
| interface MyInterface { ... } |
| </pre><p> |
| the pointcut <tt>call(* MyInterface.*(..))</tt> picks |
| out any call to a method in <tt>MyInterface</tt>'s |
| signature -- that is, any method defined by |
| <tt>MyInterface</tt> or inherited by one of its a |
| supertypes. |
| </p></li></ul></div></div><div class="sect2"><a name="call-vs-execution"></a><div class="titlepage"><div><h3 class="title"><a name="call-vs-execution"></a>call vs. execution</h3></div></div><p> |
| When methods and constructors run, there are two interesting times |
| associated with them. That is when they are called, and when they |
| actually execute. |
| </p><p> |
| AspectJ exposes these times as call and execution join points, |
| respectively, and allows them to be picked out specifically by |
| <tt>call</tt> and <tt>execution</tt> pointcuts. |
| </p><p> |
| So what's the difference between these join points? Well, there are a |
| number of differences: |
| </p><p> |
| Firstly, the lexical pointcut declarations |
| <tt>within</tt> and <tt>withincode</tt> match |
| differently. At a call join point, the enclosing code is that of |
| the call site. This means that <tt>call(void m()) |
| && withincode(void m())</tt> will only capture |
| directly recursive calls, for example. At an execution join point, |
| however, the program is already executing the method, so the |
| enclosing code is the method itself: <tt>execution(void m()) |
| && withincode(void m())</tt> is the same as |
| <tt>execution(void m())</tt>. |
| </p><p> |
| Secondly, the call join point does not capture super calls to |
| non-static methods. This is because such super calls are different in |
| Java, since they don't behave via dynamic dispatch like other calls to |
| non-static methods. |
| </p><p> |
| The rule of thumb is that if you want to pick a join point that |
| runs when an actual piece of code runs (as is often the case for |
| tracing), use <tt>execution</tt>, but if you want to pick |
| one that runs when a particular <span class="emphasis"><i>signature</i></span> is |
| called (as is often the case for production aspects), use |
| <tt>call</tt>. |
| </p></div><div class="sect2"><a name="pointcut-composition"></a><div class="titlepage"><div><h3 class="title"><a name="pointcut-composition"></a>Pointcut composition</h3></div></div><p> |
| Pointcuts are put together with the operators and (spelled |
| <tt>&&</tt>), or (spelled <tt>||</tt>), |
| and not (spelled <tt>!</tt>). This allows the creation |
| of very powerful pointcuts from the simple building blocks of |
| primitive pointcuts. This composition can be somewhat confusing |
| when used with primitive pointcuts like <tt>cflow</tt> |
| and <tt>cflowbelow</tt>. Here's an example: |
| </p><p> |
| <tt>cflow(<i><tt>P</tt></i>)</tt> picks out |
| each join point in the control flow of the join points picked out |
| by <i><tt>P</tt></i>. So, pictorially: |
| </p><pre class="programlisting"> |
| P --------------------- |
| \ |
| \ cflow of P |
| \ |
| </pre><p> |
| What does <tt>cflow(<i><tt>P</tt></i>) && |
| cflow(<i><tt>Q</tt></i>)</tt> pick out? Well, it |
| picks out each join point that is in both the control flow of |
| <i><tt>P</tt></i> and in the control flow of |
| <i><tt>Q</tt></i>. So... |
| </p><pre class="programlisting"> |
| P --------------------- |
| \ |
| \ cflow of P |
| \ |
| \ |
| \ |
| Q -------------\------- |
| \ \ |
| \ cflow of Q \ cflow(P) && cflow(Q) |
| \ \ |
| </pre><p> |
| Note that <i><tt>P</tt></i> and |
| <i><tt>Q</tt></i> might not have any join points in |
| common... but their control flows might have join points in common. |
| </p><p> |
| But what does <tt>cflow(<i><tt>P</tt></i> |
| && <i><tt>Q</tt></i>)</tt> mean? Well, it |
| means the control flow of those join points that are both picked |
| out by <i><tt>P</tt></i> and picked out by |
| <i><tt>Q</tt></i>. |
| </p><pre class="programlisting"> |
| P && Q ------------------- |
| \ |
| \ cflow of (P && Q) |
| \ |
| </pre><p> |
| and if there are <span class="emphasis"><i>no</i></span> join points that are both |
| picked by <i><tt>P</tt></i> and picked out by |
| <i><tt>Q</tt></i>, then there's no chance that there are |
| any join points in the control flow of |
| <tt>(<i><tt>P</tt></i> && |
| <i><tt>Q</tt></i>)</tt>. |
| </p><p> |
| Here's some code that expresses this. |
| </p><pre class="programlisting"> |
| public class Test { |
| public static void main(String[] args) { |
| foo(); |
| } |
| static void foo() { |
| goo(); |
| } |
| static void goo() { |
| System.out.println("hi"); |
| } |
| } |
| |
| aspect A { |
| pointcut fooPC(): execution(void Test.foo()); |
| pointcut gooPC(): execution(void Test.goo()); |
| pointcut printPC(): call(void java.io.PrintStream.println(String)); |
| |
| before(): cflow(fooPC()) && cflow(gooPC()) && printPC() && !within(A) { |
| System.out.println("should occur"); |
| } |
| |
| before(): cflow(fooPC() && gooPC()) && printPC() && !within(A) { |
| System.out.println("should not occur"); |
| } |
| } |
| </pre><p> |
| The <tt>!within(<i><tt>A</tt></i>)</tt> |
| pointcut above is required to avoid the <tt>printPC</tt> |
| pointcut applying to the <tt>System.out.println</tt> |
| call in the advice body. If this was not present a recursive call |
| would result as the pointcut would apply to it's own advice. |
| (See <a href="pitfalls-infiniteLoops.html" title="Infinite loops">the section called “Infinite loops”</a> for more details.) |
| </p></div><div class="sect2"><a name="pointcut-parameters"></a><div class="titlepage"><div><h3 class="title"><a name="pointcut-parameters"></a>Pointcut Parameters</h3></div></div><p> |
| Consider again the first pointcut definition in this chapter: |
| </p><pre class="programlisting"> |
| pointcut setter(): target(Point) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| As we've seen, this pointcut picks out each call to |
| <tt>setX(int)</tt> or <tt>setY(int)</tt> |
| methods where the target is an instance of |
| <tt>Point</tt>. The pointcut is given the name |
| <tt>setters</tt> and no parameters on the left-hand |
| side. An empty parameter list means that none of the context from |
| the join points is published from this pointcut. But consider |
| another version of version of this pointcut definition: |
| </p><pre class="programlisting"> |
| pointcut setter(Point p): target(p) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| This version picks out exactly the same join points. But in this |
| version, the pointcut has one parameter of type |
| <tt>Point</tt>. This means that any advice that uses this |
| pointcut has access to a <tt>Point</tt> from each join |
| point picked out by the pointcut. Inside the pointcut definition |
| this <tt>Point</tt> is named <tt>p</tt> is |
| available, and according to the right-hand side of the definition, |
| that <tt>Point p</tt> comes from the |
| <tt>target</tt> of each matched join point. |
| </p><p> |
| Here's another example that illustrates the flexible mechanism for |
| defining pointcut parameters: |
| </p><pre class="programlisting"> |
| pointcut testEquality(Point p): target(Point) && |
| args(p) && |
| call(boolean equals(Object)); |
| </pre><p> |
| This pointcut also has a parameter of type |
| <tt>Point</tt>. Similar to the |
| <tt>setters</tt> pointcut, this means that anyone using |
| this pointcut has access to a <tt>Point</tt> from each |
| join point. But in this case, looking at the right-hand side we |
| find that the object named in the parameters is not the target |
| <tt>Point</tt> object that receives the call; it's the |
| argument (also of type <tt>Point</tt>) passed to the |
| <tt>equals</tt> method when some other |
| <tt>Point</tt> is the target. If we wanted access to both |
| <tt>Point</tt>s, then the pointcut definition that would |
| expose target <tt>Point p1</tt> and argument |
| <tt>Point p2</tt> would be |
| </p><pre class="programlisting"> |
| pointcut testEquality(Point p1, Point p2): target(p1) && |
| args(p2) && |
| call(boolean equals(Object)); |
| </pre><p> |
| Let's look at another variation of the <tt>setters</tt> pointcut: |
| </p><pre class="programlisting"> |
| pointcut setter(Point p, int newval): target(p) && |
| args(newval) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| In this case, a <tt>Point</tt> object and an |
| <tt>int</tt> value are exposed by the named |
| pointcut. Looking at the the right-hand side of the definition, we |
| find that the <tt>Point</tt> object is the target object, |
| and the <tt>int</tt> value is the called method's |
| argument. |
| </p><p> |
| The use of pointcut parameters is relatively flexible. The most |
| important rule is that all the pointcut parameters must be bound at |
| every join point picked out by the pointcut. So, for example, the |
| following pointcut definition will result in a compilation error: |
| |
| <pre class="programlisting"> |
| pointcut badPointcut(Point p1, Point p2): |
| (target(p1) && call(void setX(int))) || |
| (target(p2) && call(void setY(int))); |
| </pre> |
| |
| because <tt>p1</tt> is only bound when calling |
| <tt>setX</tt>, and <tt>p2</tt> is only bound |
| when calling <tt>setY</tt>, but the pointcut picks out |
| all of these join points and tries to bind both |
| <tt>p1</tt> and <tt>p2</tt>. |
| </p></div><div class="sect2"><a name="example"></a><div class="titlepage"><div><h3 class="title"><a name="example"></a>Example: <tt>HandleLiveness</tt></h3></div></div><p> |
| The example below consists of two object classes (plus an exception |
| class) and one aspect. Handle objects delegate their public, |
| non-static operations to their <tt>Partner</tt> |
| objects. The aspect <tt>HandleLiveness</tt> ensures that, |
| before the delegations, the partner exists and is alive, or else it |
| throws an exception. |
| </p><pre class="programlisting"> |
| class Handle { |
| Partner partner = new Partner(); |
| |
| public void foo() { partner.foo(); } |
| public void bar(int x) { partner.bar(x); } |
| |
| public static void main(String[] args) { |
| Handle h1 = new Handle(); |
| h1.foo(); |
| h1.bar(2); |
| } |
| } |
| |
| class Partner { |
| boolean isAlive() { return true; } |
| void foo() { System.out.println("foo"); } |
| void bar(int x) { System.out.println("bar " + x); } |
| } |
| |
| aspect HandleLiveness { |
| before(Handle handle): target(handle) && call(public * *(..)) { |
| if ( handle.partner == null || !handle.partner.isAlive() ) { |
| throw new DeadPartnerException(); |
| } |
| } |
| } |
| |
| class DeadPartnerException extends RuntimeException {} |
| </pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="language-anatomy.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="language-advice.html">Next</a></td></tr><tr><td width="40%" align="left">The Anatomy of an Aspect </td><td width="20%" align="center"><a accesskey="u" href="language.html">Up</a></td><td width="40%" align="right"> Advice</td></tr></table></div></body></html> |