I have a situation where I need to use Guice 3.0 to instantiate my object but one of the values will change potentially with each instance. I cannot bind that value's type and I won't know until I need to create the instance.
For instance:
public class Foo {
public Foo(Bar bar, Baz baz) {...}
}
I want Guice to inject the Bar
param but I won't know Baz
until I need Foo
. The value isn't scope-specific (e.g. RequestScope) either.
The whole reason I want this object fully instantiated by Guice is because I need method interception. In Guice, "manually constructed instances do not participate in AOP".
I've tried to do this with Provider<Foo>
but that only allows me public Foo get() { ... }
.
It would be a configuration nightmare to have to create a provider for every possible value of Baz
, so I can't simply have Baz
be defined in FooProvider's constructor.
I feel like I'm missing something fundamental here. Perhaps it is because it is the last thing I'm doing on a Friday. Any ideas would be appreciated.
Edit: The answer below to use "assisted injection" seems to only work if you have the ability to edit the source of Foo
. Foo
may actually be outside of my control for some instances. And if I create the instances myself (i.e., implement my own factory) then Guice-AOP method interceptors don't seem to ever know about the object.
It looks like "assisted injection" might be a solution:
Except it doesn't work if you don't have access to annotate the constructor of Foo
.
EDIT: what I have found is that I am able to add the assisted injection annotations by extending the type and adding them to the constructor that I wish to use:
public class AssistedFoo extends Foo {
@AssistedInject
public AssistedFoo(
Bar bar,
@Assisted Baz baz) {
super(bar, baz);
}
}
Then use this extended implementation in the assisted injection registration:
public interface FooFactory {
Foo create(Baz baz);
}
//...
install(new FactoryModuleBuilder()
.implement(Foo.class, AssistedFoo.class)
.build(FooFactory.class));
The extra inheritance class is only needed when you don't have access to change Foo
. Obviously this workaround wouldn't work if the class is final
.