3 Replies Latest reply on Feb 6, 2004 11:45 AM by rythos

    added Aspects

    bill.burke

      I just added a new feature in HEAD (cvs checkout jboss-head)

      Added the ability to define Aspects. Aspects are a Java class that contains multiple advices. An advice in an Aspect class maps to a particular method.

      Here's what the XML and code looks like. POJOAspectTester is what we're interception. Aspect is the class that contains advices. The XML defines the aspect and then binds the advice of the aspect within a pointcut.

      You can define a scope for the aspect. This is PER_VM, PER_CLASS, or PER_INSTANCE. (FYI, i'll be adding this for interceptors soon too).

      Note on performance. Aspects are much slower than regular interceptors because reflection is required to execute the advices where regular interceptors this is not required.

       [aspect class="org.jboss.test.aop.bean.Aspect" scope="PER_VM"/]
      
       [constructor-pointcut constructor="org.jboss.test.aop.bean.POJOAspectTester()"]
       [bind]
       [advice name="interceptConstructor" aspect="org.jboss.test.aop.bean.Aspect"/]
       [/bind]
       [/constructor-pointcut]
      
       [method-pointcut class="org.jboss.test.aop.bean.POJOAspectTester" methodExpr="void someMethod()"]
       [bind]
       [advice name="interceptMethod" aspect="org.jboss.test.aop.bean.Aspect"/]
       [/bind]
       [/method-pointcut]
      
      
      
      public class POJOAspectTester
      {
       public String marker = "error";
       public int field;
      
       public POJOAspectTester() {}
      
       public void someMethod() {}
      }
      
      public class Aspect
      {
       public Object interceptConstructor(ConstructorInvocation invocation) throws Throwable
       {
       Object rtn = invocation.invokeNext();
       POJOAspectTester pojo = (POJOAspectTester)rtn;
       pojo.marker = "interceptConstructor";
       return rtn;
       }
      
       public Object interceptField(FieldInvocation invocation) throws Throwable
       {
       Object rtn = invocation.invokeNext();
       POJOAspectTester pojo = (POJOAspectTester)invocation.targetObject;
       pojo.marker = "interceptField";
       return rtn;
       }
      
       public Object interceptMethod(MethodInvocation invocation) throws Throwable
       {
       Object rtn = invocation.invokeNext();
       POJOAspectTester pojo = (POJOAspectTester)invocation.targetObject;
       pojo.marker = "interceptMethod";
       return rtn;
       }
      }
      



        • 1. Re: added Aspects
          marc.fleury

          explain this to us.

          1- you always start the aspect code with invocation.invokeNext(); this reads is if you always invoke the object first so there is nothing you do in a "pre sense". Is that only for this example?

          2- I am a little confused on the scope.
          The aspect defines "my scope" is the VM
          Then the poincut defines a binding for a method in a class for example. Why the "VM" scoping then? The class scope is confusing still, if you define a pointcut to bind an aspect to a class method, why do you need "scoping".

          3- One scoping mechanism that would leverage separate names in the "aspect" and the "poincut" would be application scoping (aka logical scoping). You would define "aspect scope = someName", then define the binding be applied to logical scopes so the matching within the pointcut binding is done on a class method but only those instances that are attached to a given application. Defining "application" relation on instances is going to be a bit trickier. Maybe new() should leverage a "threadlocal" variable that marks belonging to the app. For server side IoC would could automate that in teh same way.

          • 2. Re: added Aspects
            bill.burke

            Ok, terms:

            Aspect: container of advices
            Advice: is attached behavior that you want called when the pointcut is intercepted

            The Aspect in the example is a plain java class. The advices are NON STATIC methods. An aspect must be allocated to invoke the advices. The SCOPE defines whether the aspect will be:

            PER_VM: One instance for the whole VM
            PER_CLASS: One instance for the class
            PER_INSTANCE: One instance of the aspect per object instance.

            So, binding states that I want a particular advice called when a pointcut(a method call, field access, etc...) is reached. An advice is attached and called through the aspect instance. Where the aspect instance lives is dependent on the SCOPE. (See above).

            The code within the Aspect class is just an example of advices in action.

            Make sense now?

            Bill

            • 3. Re: added Aspects
              rythos

              It's used in cases where you want some state associated with each object that is being advised, but you don't want to do introduction to add extra fields. (Or you can't do introduction easily, as there is no abstract base class in common).

              Ladded (AspectJ in Action) uses this functionality to implement a per object read-write lock which is quite elegant.