Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] AspectJ Runtime Hooks for Object Persistence

Hi -

> The only issue is how to assign these two aspects at runtime to
whatever class I want

If/since you're willing to write a class loader and weave at runtime,
I'm sure you could
figure out how to limit the class targets or regenerate the aspect on
the fly.  However,
I strongly believe that all aspects should be defined before any classes
are, and that
all aspects should apply to all classes.  The cases where this is not
true are so limited
that it's not worth using AspectJ; you might as well just use javassist.

In any case, with your current interceptor delegate, you must have code
of the form:    {interceptible}.setInterceptor(i);
Perhaps that's the point at which to make runtime decisions.  That does
imply
every class in your package has the interceptor protocol built in. To
reduce the cost
for non-intercepted g/setters in the target package, change the pointcut
so the
advice runs only when there is an interceptor (and don't set a default
one):
    before(Interceptable i): getter(i) && if(null != i.getInterceptor())
{
        i.getInterceptor().getField(i,
thisJoinPoint.getSignature().getName());
    }


Overall, it looks like you're taking a reflective approach and using
AspectJ/AOP to wire it up.
Your interceptors are limited to snooping (before advice); around advice
could change
the actual values or flow of control.  One alternative design is to have
the interceptor be the
interface, rather than a delegate (assuming you don't have families of
interceptors to
interpose).  Another is to put the snooping logic directly into the
advice.  Still another
is to encapsule the idiom of checking getters/setters in an abstract
aspect with template
methods for the snooping, and then implement those for each type
snooped; that gives
you type-safe downwards casts so you can avoid reflection altogether.
Also, then
you could instantiate the concrete aspects using pertarget to get
per-object state (e.g.,
for journalling and rollback).  And I'm sure there's more ways; I'd be
surprised if there
were less than 10 ways to do variants of interception in AspectJ.

Have fun -
Wes

P.S.  There's a new FAQ entry on the issue of runtime weaving and
declarations:
 http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/faq.html#q:loadtimeWeaving

P.P.S. - LCD plain text emails preferred...

"Sean R. Drucker" wrote:

> AspectJ worked great.  Below is what I came up with.  The only issue
> is how to assign these two aspects at runtime to whatever class I want
> (as apposed to declaring it statically).  Anyone know were I can
> look?Thanks... Seanaspect InterceptPointcuts {    private Interceptor
> Interceptable.interceptor = Passthrough.DEFAULT;    public void
> Interceptable.setInterceptor(Interceptor i) {
>         interceptor = i == null ? Passthrough.DEFAULT : i;
>     }
>     public Interceptor Interceptable.getInterceptor() {
>         return interceptor;
>     }    declare parents : persistence.objects.* implements
> Interceptable;
> }aspect Intercept {    pointcut getter(Interceptable i):
>         get(!transient * (persistence.objects.*).*) && target(i);
> pointcut setter(Interceptable i, Object value):
>         set(!transient * (persistence.objects.*).*) && target(i) &&
> args(value);    before(Interceptable i): getter(i) {
>         i.getInterceptor().getField(i,
> thisJoinPoint.getSignature().getName());
>     }    before(Interceptable i, Object value): setter(i, value) {
>         i.getInterceptor().setField(i,
> thisJoinPoint.getSignature().getName(), value);
>     }}
>
>      -----Original Message-----
>      From: aspectj-users-admin@xxxxxxxxxxx
>      [mailto:aspectj-users-admin@xxxxxxxxxxx]On Behalf Of Sean R.
>      Drucker
>      Sent: Saturday, March 01, 2003 9:48 AM
>      To: aspectj-users@xxxxxxxxxxx
>      Subject: [aspectj-users] AspectJ Runtime Hooks for Object
>      Persistence
>      Can anyone point me in the right direction for doing the
>      following (can AspectJ do this?): -At runtime, using
>      weaving, load a class and declareall field get and set
>      pointcuts for all non-transient fields in the class.
>      Obviously, field point-cuts from outside the class can not
>      be created as they require access to the calling code.  This
>      is not an issue. -At runtime, be able to hook/unhook the
>      object with a single object to intercept the field
>      pointcuts.  Only one hook object can be attached to the
>      weaved object at a time. Thanks... Sean  Reasons for doing
>      this (if you care): -Developing a large object persistence
>      project (>100 classes).-Depending on the usage of the
>      persistence object, the fields will be loaded using
>      different fetching schemes.  Therefore, the fields that need
>      to be intercepted (to do the background fetching) can vary
>      at runtime.  Sample: public class Employee {
>          private String name;
>          private transient int setCount;     public String
>      getName() {
>              return name;
>          }
>          public void setName(String name) {
>              setCount++;
>              this.name = name;         // edge case
>              assert ((this.name = this.name) == this.name);
>          }}  Could be weaved as follows:
>      public class Employee implements Interceptable {
>          private String name;
>          private transient int setCount;     public String
>      getName() {
>              return (String)interceptor.getField(this, "name",
>      name);
>          }
>          public void setName(String name) {
>              setCount++;
>              this.name = (String)interceptor.setField(this,
>      "name", this.name, name);         // edge case
>              assert ((this.name =
>      (String)interceptor.setField(this, "name", this.name,
>                      (String)interceptor.getField(this, "name",
>      this.name))) ==
>                      (String)interceptor.getField(this, "name",
>      this.name));
>          }     // implement hook
>          public void setInterceptor(Interceptor interceptor) {
>              this.interceptor = interceptor == null ?
>      Passthrough.DEFAULT : interceptor;
>          }
>          public Interceptor getInterceptor() {
>              return interceptor;
>          }     private Interceptor interceptor =
>      Passthrough.DEFAULT;}Passthrough/Interceptor: public class
>      Passthrough implements Interceptor {     public static final
>      Interceptor DEFAULT = new Passthrough();     public Object
>      getField(Object obj, String field, Object currentValue) {
>              return currentValue;
>          }    public Object setField(Object obj, String field,
>      Object currentValue, Object newValue) {
>              return newValue;
>          }
>      }Thanks...
>



Back to the top