A good way to visualize annotations is to think of classnames, method names, field names, and constructor signatures as nouns, and annotations/metadata as adjectives. You can declare advice/interceptor bindings like: All @Remotable objects should register with a dispatcher whenever they are constructed. Any method marked @Transactional begin/commit/rollback a transaction at the start and end of the method. Or even any field, method, constructor marked @Traceable, do tracing. It kinda lets the application developer give hints to the aspect developer. If you think about it another way, combining annotations and AOP allows you to plug in new Java keywords. Kinda like C pre-processor macros on steroids. Macros that are typesafe and checked by the compiler and unlike Major League Baseball players, it will always be legal for you to use these steroids in your applications.
@Trace @Billable public void someMethod() { System.out.println("someMethod"); }In the above example, we are declaring someMethod() to be traced and billable.
$ javac MyFile.java
<bind pointcut="execution(POJO->@Billable(..))"> <interceptor class="BillingInterceptor"/> </bind> <bind pointcut="execution(* POJO->@Billable(..))"> <interceptor class="BillingInterceptor"/> </bind>
The first binding above says that for every constructor tagged as @Billable apply the BillingInterceptor. The second binding states that for any method tagged as @Billable apply the BillingInterceptor. Let's now take a look at applying the tracing advice.
<bind pointcut="all(@Trace)"> <interceptor class="TraceInterceptor"/> </bind>
The above states that for any field, constructor, or method tagged as @Trace, apply the TraceInterceptor.
To compile and run (for further detail, refer to our Compiling and Running Examples Guide):
$ ant run.aopc
It will javac the files and then run the AOPC precompiler to manipulate the bytecode, then finally run the example. The output should be similar to this:
_run.aopc: [java] --- new POJO(); --- [java] billing...org.jboss.aop.joinpoint.ConstructorInvocation@1ee4648 [java] <<< Trace : executing constructor public POJO() [java] empty constructor [java] >>> Leaving Trace [java] --- new POJO(int); --- [java] <<< Trace : executing constructor public POJO(int) [java] int constructor [java] >>> Leaving Trace [java] --- pojo.someMethod(); --- [java] billing...org.jboss.aop.joinpoint.MethodInvocation@1b383e9 [java] <<< Trace : executing method public void POJO.someMethod() [java] someMethod [java] >>> Leaving Trace [java] --- pojo.field = 55; --- [java] <<< Trace : write field name: public int POJO.field [java] >>> Leaving Trace