Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] @DeclareParents delegates while "declare parents : " is woven in.

The short question is:
When using @DeclareParents to define a mixin, how do I gain access to
the instrumented object from within the mixin object?

The long version is:
The @DeclareParents annotation seems to work via delegating to an
instance of the implementation class, where "declare parents : "
actually seems to weave the code of the implementation class in.  I
found this when trying to provide dynamic behavior based on the value
of class annotations.  A call to getClass() in the mixin
implementation will return the mixin implementations class, but the
same call to getClass() when using the standard aspectj language to
create a mixin will return the aspected class.  While this does
violate one of the stated goals of the annotation-style project (that
annotations will behave identically to thier language based
conterparts), it would be easy to live with if there was a way to
access the object being extended by the mixin instance.

Possible solution/improvement:
I really like the JBoss @Mixin implementation.  @Mixin is a method
level annotation.  The method takes a single argument (The class the
mixin will be a delegate for), and it must return the delegate object
which provides the implementation.


I also saw this problem mentioned briefly in this tutorial
(http://www.damnhandy.com/?page_id=56).


Named.java
--------------------------------------------------
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  public @interface Named  {
     public String value();
  }






INamed.java
--------------------------------------------------
  public interface INamed {

      // gets name() from this classes @Named annotation
      public String getName();

      // just calls getClass()
      public Class getMyClass();
  }





NamedImpl.java
---------------------------------------------------
  public class NamedImpl implements INamed{
    public String getName() {
          Named named = this.getClass().getAnnotation(Named.class);
          return named == null ? null : named.value();
     }
     public Class getMyClass() {
           return this.getClass()
     }
  }







NamedObject.java
------------------------------------------------------
  @Named("hello")
  public class NamedObject {
  }








NamedObjectTest.java
------------------------------------------------------
import junit.framework.TestCase;

public class NamedObjectTest extends TestCase {
    public void testGetName(){
        NamedObject obj = new NamedObject();
        INamed named = (INamed) obj;
        assertEquals("hello",named.getName());
    }

    public void testGetMyClass(){
         NamedObject obj = new NamedObject();
         INamed named = (INamed) obj;
         assertEquals(NamedObject.class, named.getMyClass())
    }
}


--------------------------------------------------------------------------------





--
James Talmage
Owner
JR Technical
248 - 259 - 3137


Back to the top