The HAS and HASFIELD operator
The HAS operator within a pointcut expression allows you to inquire about extra information of the pointcut's target class. Let's say you have an constructor execution pointcut:
You can add a HAS expression to narrow down the expression to include the execution of any constructor who's class has a method setValue:
execution(*->new(..)) AND has(void *->setValue(int))
You can also do the same with fields. Let's say we also wanted to narrow it down to all classes that have a Thread field:
execution(*->new(..)) AND hasfield(java.lang.Thread *.*)
Inversion of Control
How is this useful? A usecase is Inversion of Control (IoC). IoC is about injecting an object's depencies transparently. You could define an aspect that intercepted a constructor call, and on the return inject these dependencies into the object. The has operator allows you to do this and this is what the example program does.
The example uses the following binding:
<bind pointcut="execution(*->new(..)) AND has(public void *->setInjectedParameter(int))"> <interceptor class="DependencyInjectorInterceptor"></interceptor> </bind>
On any constructor call where the constructor's class has a public setInjectedParameter method, call the DependencyInjectorInterceptor. The DependencyInjectorInterceptor will call the constructed object's setInjectedParameter.
The AOP Asynchronous Method Invocation framework also uses has in an introduction class expression so that a class-level tag does not need to be specified, but rather, have the introduction be attached based on whether or not a method is tagged as asynchronous.