An Introduction to Aspect-Oriented programming with JBoss AOP
Lightweight Advice Methods
The advices that we have seen so far have been around advices, which have been part of JBoss AOP since its inception. They allow you to add behaviour both before or after invoking the target joinpoint. As seen, these all take a parameter of type Invocation, or a subclass thereof. In a heavily woven application, every time you want to call a joinpoint that has advice methods applied to it, the AOP framework needs to instantiate the Invocation object, and this can pose some overhead. To bring JBoss AOP more in line with what is offered by other AOP frameworks, we have introduced the concept of lightweight advice methods, which do not require the instantiation of an Invocation object. The Invocation object contains quite a lot of conceptual information about what is being called, but we can still obtain most of this using other means. Going back to our logging example, we can rewrite the LoggingAspect for what to do when fields are written to:
package bank;
import org.jboss.aop.advice.annotation.Arg;
import org.jboss.aop.advice.annotation.JoinPoint;
import org.jboss.aop.advice.annotation.Target;
import org.jboss.aop.joinpoint.FieldAccess;
public class LoggingAspect
{
public void logBefore(@JoinPoint FieldAccess fieldAccess, @Target BankAccount account, @Arg int value)
{
System.out.println("F: setting field " + fieldAccess.getField().getName() + " for BankAccount " + account.getAccountNumber());
System.out.println("F: Field old value " + account.getBalance());
System.out.println("F: New value will be " + value);
}
public void logAfter(@Target BankAccount account)
{
System.out.println("F: Field new value " + account.getBalance());
System.out.println("F: Done");
}
}
The original log method has been split into two methods. A before advice logBefore() which will be triggered before the field is written to, and an after advice logAfter() that will be triggered after the field is written to. For the logBefore() method the fieldAccess parameter annotated with @JoinPoint contains information about the field, the @Target annotated account parameter receives the object whose field we are writing to, and the @Arg annotated value parameter receives the new value we are setting the field to. Similarly, for the logAfter() method the account parameter annotated with @Target receives the object whose field we set. Note that since lightweight advice methods never receive an Invocation parameter there is no need to call Invocation.invokeNext(). The JBoss AOP framework knows which advices to call before and after the joinpoint is called. To bind these advices we use the following xml:
<aop>
<aspect class="bank.LoggingAspect"/>
<bind pointcut="set(* bank.BankAccount->balance)">
<before aspect="bank.LoggingAspect" name="logBefore"/>
<after aspect="bank.LoggingAspect" name="logAfter"/>
</bind>
</aop>
This is similar to our previous logging example, but instead of using “around” in our binding, we now have a “before” and “after” entry, specifying that logBefore() should be called before the field is written to, and logAfter() should be called after the field is written to. Running this example we get the following output:
*** Creating account 1
*** Bank Account constructor
*** BankAccount.credit()
F: setting field balance for BankAccount 1
F: Field old value 0
F: New value will be 150
F: Field new value 150
F: Done
*** Creating account 2
*** Bank Account constructor
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 0
F: New value will be 230
F: Field new value 230
F: Done
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
*** BankAccount.debit()
F: setting field balance for BankAccount 1
F: Field old value 150
F: New value will be 100
F: Field new value 100
F: Done
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 230
F: New value will be 280
F: Field new value 280
F: Done
*** Balance acount 1: 100
*** Balance acount 2: 280
In addition to “before” and “after”, you also have “throwing” advices which are called when the target joinpoint throws an exception, and “finally” advices which are called after the target joinpoint regardless of if it resulted in an exception or not. As we have seen “after” advices are called after the target joinpoint has been called, if no exception was thrown.
The code for this example can be found in the listing4/ folder of the download bundle.
| Attachment | Size |
|---|---|
| jboss-aop-samples.zip | 4.76 MB |
- Login or register to post comments
- 21954 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Joshua Partogi replied on Fri, 2008/08/29 - 10:05pm
jaikiran replied on Sat, 2008/08/30 - 3:52am
Good article, Kabir.
I have a question. Is the aspect code allowed to change the value that is being passed to the joinpoint? I mean, if the credi(int amount) method was being passed a value of 200, can the code in the aspect change this value to 100 before the credit method is invoked? If yes, is there any way to secure such access?
Kabir Khan replied on Mon, 2008/09/01 - 5:06am
Joshua,
Yes annotations can be used instead.An example can be found here and the containing directory contains more examples. If using annotations, instead of passing in the path of a jboss-aop.xml file with -Djboss.aop.path, you point JBoss AOP to a directory containing your annotated aspects using -Djboss.aop.class.path. The tutorial examples that come with the download will show how in more detail.
Kabir Khan replied on Mon, 2008/09/01 - 5:13am
Jaikiran,
The aspect code can modify the values that are passed in. There is currently no way to stop this, if that is what you mean by securing it. If this feature is important to you please ask for it on our user forums, and we will take it into consideration.
gsowji replied on Tue, 2009/02/10 - 11:37pm
gsowji replied on Wed, 2009/02/11 - 1:18am
daveeeed replied on Fri, 2009/06/05 - 2:54am
warrenty replied on Mon, 2009/06/08 - 1:40am
modthoa replied on Wed, 2009/06/17 - 10:51am
emad964 replied on Mon, 2009/06/29 - 4:14pm
jiji530 replied on Mon, 2009/06/29 - 9:42pm
wikaniko replied on Thu, 2009/07/09 - 1:02pm
superpan3721 replied on Sat, 2009/08/01 - 1:38am
nakul replied on Tue, 2009/10/20 - 1:49pm
in response to: thejavafreak
markgrant1st replied on Wed, 2009/11/04 - 2:27am
Wish I could learn the programming . I know each and everything about the Markets but computer, me and computer can not be friends at all :)\
Home Insurance Rates
Teddy P replied on Thu, 2009/11/05 - 9:46am
abcdentist replied on Sun, 2009/11/08 - 2:57am
hpmedia replied on Sun, 2009/11/08 - 8:44pm
hpmedia replied on Tue, 2009/11/17 - 5:40pm