JBoss.org Community Documentation
As mentioned, you can add more aspects to a woven class using the
org.jboss.aop.InstanceAdvisor
. This API is limited to adding
interceptors to the existing intereptor chains, so it is a bit limited.
The new default weaving mode introduced in JBoss AOP 2.0.0 still allows you access to the
InstanceAdvisor
interface, but also offers a fuller instance API, which allows you to add bindings,
annotation overrides etc. via the normal dynamic AOP API. This is underdocumented,
but for a full overview of the capabilites take a look at how
org.jboss.aop.AspectXmlLoader
interacts with
org.jboss.aop.AspectManager
. We are working on a new tidier API for
the next version of JBoss AOP. Normally, for dynamic AOP you add
things to the top level AspectManager
, which means that all instances
of all woven classes can be affected.
In JBoss AOP 2.0.0, each aspectized class has its own Domain. A domain is a sub-AspectManager.
What is deployed in the main AspectManager is visible to the class's domain, but not vice versa.
Furthermore each advised instance has its own Domain again which is a child of the class's domain.
The Domain class is a sub-class of the AspectManager, meaning you can add ANYTHING supported by
JBoss AOP to it, you are not limited to just interceptors. In the following example we prepare
all joinpoints of the POJO class and declare an aspect called MyAspect
<!-- Weave in the hooks into our POJO class and add the interceptors --> <aop> <aspect class="MyAspect"/> <prepare expr="all(POJO)"/> </aop>
POJO pojo1 = new POJO(); POJO pojo2 = new POJO();
pojo1.someMethod();
At this stage, our POJO
has the hooks woven in for AOP, but now bindings are deployed, so our call
to POJO.someMethod()
is not intercepted. Next let us add a binding to POJO
's class domain.
//All woven classes implement the Advised interface Advised classAdvisor = ((Advised)pojo1); //Get the domain used by all instances of POJO AspectManager pojoDomain = classAdvisor._getAdvisor().getManager(); //Add a binding with an aspect for that class this is similar to AdviceBinding binding1 = new AdviceBinding("execution(* POJO->someMethod*(..))", null); AspectDefinition myAspect = AspectManager.instance().getAspectDefinition("MyAspect"); binding1.addInterceptorFactory(new AdviceFactory(myAspect, "intercept")); //Add the binding to POJO's domain pojoDomain.addBinding(binding1); pojo1.someMethod(); pojo2.someMethod();
Now we have added a binding to POJO
's class Domain. Both calls to
someMethod()
get intercepted by MyAspect
//Create an annotation introduction AnnotationIntroduction intro = AnnotationIntroduction.createMethodAnnotationIntroduction( "* POJO->someMethod()", "@MyAnnotation", true); //Create another binding AdviceBinding binding2 = new AdviceBinding("execution(* POJO->@MyAnnotation)", null); binding2.addInterceptor(MyInterceptor.class); //All woven instances have an instance advisor InstanceAdvisor instanceAdvisor1 = ((Advised)pojo1)._getInstanceAdvisor(); //The instance advisor has its own domain Domain pojo1Domain = instanceAdvisor1.getDomain(); //Add the annotation override and binding to the domain pojo1Domain.addAnnotationOverride(intro); pojo1Domain.addBinding(binding2); pojo1.someMethod(); pojo2.someMethod();
We have added an annotation override and a new binding matching on that annotaton to pojo1
's domain, so
when calling pojo1.someMethod()
this gets intercecpted by MyAspect
AND MyInterceptor
. pojo2.someMethod()
still gets intercepted by MyAspect only.