Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Help with a Dependency Passing Aspect

Thanks for the response. I'll answer your questions as best I can.

How is foo associated with the method anotherExample? It's not defined on
Foo in the example.

The idea is that Foo has some resource that all of its members need,
like a database connection factory, information specific to the Foo
object graph, etc. In effect, it's a cross-cutting concern that is
different for each object graph. So, for example, if each member of
Foo's graph needs to know the name of the graph to do some processing:

class Foo {
 // Things from previous example removed for brevity.
 private String name;
 public Foo(String name) {
   this.name = name;
 }
 public String getName() {
   return name;
 }
}

class Bar {
 // Things from previous example removed for brevity.
 public void doProcessing() {
   // For some reason, I need the name of my root Foo:
  String myFooName = root.getName();
 }
}

Could you extend your approach to also initialize the
Bar types that are created via FooBarFooFactory, by accessing Bar.getRoot()?

Sure, that's the way that I would envision it working in AOP. Each
member of a graph would know its root, and when a member creates a new
member, it passes on the result of its getRoot() method to whatever it
creates.

I should point out that after a bit of work this morning, I got
something similar working in AOP. Essentially, I used my original
aspect and forced all of the object graph members to access factories
and the database layer through Foo, basically forcing object creation
to flow through Foo. It actually worked, but according to YourKit, I
spent about 20% of my processing inside of the CFlow push and pop
methods.  Since construction of my member objects could occur outside
of a class that I control, such as the database layer which uses
reflection to create the object, I think that I'll have to use cflow.
If the performance overhead of using cflow that much is going to be
~20%, I'll need to find a different solution or a different way of
looking at the problem.

Matt

-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx
[mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Matt Kendall
Sent: Thursday, May 17, 2007 9:19 AM
To: aspectj-users@xxxxxxxxxxx
Subject: [aspectj-users] Help with a Dependency Passing Aspect

I've been trying to figure out this aspect for the past few hours.
Hopefully someone can help since I'm new to AOP. I'm working on a
project where I have several Foo objects that are the root of object
graphs. The members of each Foo graph need to access Foo on a regular
basis, but they need to access the Foo to which they belong (not a
global singleton). If I wanted to maintain a whole lot of extra code,
I'd write something like this to accomplish what I want:

class Foo {
  public FooBar getSomeResource() {
    return someResource;
  }
  public Bar anExample() {
    Bar bar = BarFactory.createABar(this); // Creates and returns a Bar
                                                             // that
has a reference to this Foo.
    return bar;
  }
}

class Bar {
  private Foo root;
  public Bar(Foo root) {
    this.root = root;
  }
  public FooBarFoo anotherExample() {
    return FooBarFooFactory.createAFooBarFoo(root);
  }
}

Hopefully that makes some amount of sense. My original tactic, which
worked quite well at first, was to use the following aspect:

public aspect FooInitializer {
  pointcut withinFoo(Foo foo): within(Foo) && this(foo);
  pointcut initialize(FooWorker bar, Foo foo):
initialization(FooWorker.new(..)) && target(bar) &&
cflow(withinFoo(foo));
    before(FooWorker bar, Foo foo): initialize(bar, foo) {
    bar.initialize(foo);
  }
}

Basically, any class that needed an instance of Foo in order to do its
work just implemented the FooWorker interface and the dependency was
injected. Unfortunately, that aspect won't work if a member object of
Foo escapes its cflow. For example, using the code from above:

Foo foo = new Foo();
Bar bar = foo.anExample();
FooBarFoo fbf = foo.anotherExample(); // Will not be initialized
because it wasn't
                                                         // created in
the cflow of Foo.

So, what I'm looking for is a way to *pass* a dependency to any object
created by an object that knows about said dependency. Note that I
cannot just look for calls
to constructors directly, since the member object may be created in a
factory or the database layer.

Hopefully that makes some sort of sense. Thanks for reading!
Matt
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top