Just figured that Dagger currently doesn't do any "Lifecycle management", and won't invoke @PostConstruct annotated methods after the constructors, nor has stop() / close() kinda API on gen. @Component to invoke @PreDestroy annotated methods. (PostConstruct & PreDestroy are from JSR 250 in javax.annotation and in the JDK rt.jar since Java 6.)
Opening this issue to understand if there is (a) fundamental opposition to ever supporting this in principle; or (b) just something you haven't gotten around it - and would potentially welcome a contribution for?
Rationale: I like Dagger's "minimalistic" (certainly compared to Spring Core, but also to Guice) approach, but lifecycle support seems basic to DI. It's possible that this view is "skewed" - I'm looking at Dagger from the angle of using it in an dynamic platform where being able to e.g. unregister listeners is crucial. In my case this is for an OSGi-based thing (ODL), but even in a Servlet container for clean WAR hot reload, or presumably in Android which I understand is G's primary target for Dagger, this seems fairly essential ... but perhaps I am missing something?
If it's (a) then please feel do free to close this with a short comment - at least the next person searching around for this will hit this and understand... ;-) If it's (b) perhaps a word of how feasible this would be to contribute - from a VERY quick thought about this, it shouldn't be THAT hard, no? Make every _Factory's get() call the @PostConstruct annotated method after the constructor call, and have an (java.lang.AutoCloseable ?) close() on the gen. @Component to close() each of its... Provider? (Ha, this may be the trickier part, the instances aren't kept? Or maybe I'm just confused about the @Singleton and scoping, from the first glance at the gen. code.)
FTR, I've come across @alexec's approach with a "manual" LifeCycleManager class with a register() invoked inside each @Provides of a Module - that (probably, ordering?)... works, of course, but is too explicit, for my taste.
In the mean time, Guice instead of Dagger it is for the project I've looked at Dagger for... snif! :(
As for @PostConstruct, you can use method injection to achieve the same goal:
class MethodInject {
@Inject MethodInject(...) {
}
@Inject public void postConstruct() {
System.out.println("hello-world");
}
}
As for @PreDestroy, @netdpb has been working on some memory-management features internally but we're not ready to release that API yet, it's still in flux.
The short answer is that Dagger won't be implementing @PostConstruct or `@PreDestroy. (Never say never, but… pretty much never.)
For the vast majority of applications, the lifecycle of the object seems to be sufficient. As @ronshapiro pointed out, @PostConstruct isn't significantly different from method injection , but @PreDestroy is where things get tricky. Implementations that track the end of a lifecycle usually incur high costs in terms of the infrastructure needed (references, state checking, etc.) and greatly increase the surface area for bugs (leaks and such). It's not _that_ fundamentally different from a finalizer in that regard.
I think it makes sense in the Java EE world where the objects are almost _designed_ to be these heavyweight, complicated constructs that exist as services written on top of other services, but not nearly so much in Java SE -- I don't know how these and @Resource were considered "common'.
That said, there are times that you have to explicitly manage some lifecycles and I would highly recommend you do that manually. Guava provides Service and ServiceManager, and have worked very well for me. If you multibind a set of services and give them to the service manager, you can cover many of the same use cases in a way that is quite a bit more robust (IMO).
One good reason I can think of for @PreDestroy is to do a close() on JDBC Connections that were opened earlier in a more "well defined spot"
As far as @PostConstruct I think that constructor injection should be sufficient especially with the Lazy capability.
Primary usage of @PreDestroy is a clean application shutdown. Beans instantiated according to the dependency graph, and should be stopped in the reverted order. Manually figure out revert order of startup? IoC already has that information.