Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[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


Back to the top