package com.netflix.governator;
import com.google.inject.Injector;
import com.netflix.governator.spi.LifecycleListener;
/**
* Wrapper for Guice's Injector with added shutdown methods.
*
* <b>Invoking shutdown from outside the injector</b>
* <pre>
* <code>
* LifecycleInjector injector = new Governator().run();
* // ...
* injector.shutdown();
* </code>
* </pre>
*
* <b>Blocking on the injector terminating</b>
* <pre>
* <code>
* LifecycleInjector injector = new Governator().run(;
* // ...
* injector.awaitTermination();
* </code>
* </pre>
*
* <b>Triggering shutdown from a DI'd class</b>
* <pre>
* <code>
* {@literal @}Singleton
* public class SomeShutdownService {
* {@literal @}Inject
* SomeShutdownService(LifecycleManager lifecycleManager) {
* this.lifecycleManager = lifecycleManager;
* }
*
* void someMethodInvokedForShutdown() {
* this.lifecycleManager.shutdown();
* }
* }
* }
* </code>
* </pre>
*
* <b>Triggering an external event from shutdown without blocking</b>
* <pre>
* <code>
* LifecycleInjector injector = new Governator().run(;
* injector.addListener(new LifecycleListener() {
* public void onShutdown() {
* // Do your shutdown handling here
* }
* });
* }
* </code>
* </pre>
*/
final public class LifecycleInjector extends DelegatingInjector implements AutoCloseable {
private final LifecycleManager manager;
private final LifecycleShutdownSignal signal;
public static LifecycleInjector createFailedInjector(LifecycleManager manager) {
return new LifecycleInjector(null, manager);
}
public static LifecycleInjector wrapInjector(Injector injector, LifecycleManager manager) {
return new LifecycleInjector(injector, manager);
}
private LifecycleInjector(Injector injector, LifecycleManager manager) {
super(injector);
this.manager = manager;
if (injector != null) {
this.signal = injector.getInstance(LifecycleShutdownSignal.class);
}
else {
this.signal = new DefaultLifecycleShutdownSignal(manager);
}
}
/**
* Block until LifecycleManager terminates
* @throws InterruptedException
*/
public void awaitTermination() throws InterruptedException {
signal.await();
}
/**
* Shutdown LifecycleManager on this Injector which will invoke all registered
* {@link LifecycleListener}s and unblock awaitTermination.
*
* @deprecated use LifecycleInjector.close() instead
*/
@Deprecated
public void shutdown() {
signal.signal();
}
/**
* Register a single shutdown listener for async notification of the LifecycleManager
* terminating.
* @param listener
*/
public void addListener(LifecycleListener listener) {
manager.addListener(listener);
}
@Override
public void close() {
shutdown();
}
}