Yes, this should work. It's OK for the process of constructing one instance to cause other injections to occur (in fact, this is the way dependency injection works normally).
A probably better alternative for the same effect would be:
@Inject Foo(Provider<Bar> barProvider) {
this.bar = barProvider.get();
}
Since this will cause Guice to construct the Bar
instance and inject its fields.
As an aside, this example demonstrates some bad practices:
- It's bad form to make
@Inject
constructors public
. The whole point of dependency injection is to make it so that clients of your class don't need to know about your class's dependencies. That's subverted if they ever construct the class directly. If you really want a "default" constructor, just provide a non-@Inject
constructor or a factory method (either on the class or elsewhere in the package).
injectMembers
is usually a best avoided if possible. Wherever possible, prefer constructor injection. Among other things, this is necessary if you're going to be sharing instances across threads, since injectMembers
may not guarantee safe publication. Like any post-constructor initialization step, it also makes class invariants harder to reason about.
- As you've probably inferred, injecting the
Injector
is a code smell. Outside of really heavy metaprogramming or framework code, it should almost never be necessary. Like reflection, it can be a great way to build "magic" functionality, but also like reflection, it can also cause extremely weird runtime errors if you do it wrong.