LifeCycleManager { public void start() throws Exception { if (!state.compareAndSet(State.LATENT, State.STARTING)) { throw new Exception("System already starting"); } log.info("Life cycle starting..."); for (Object obj : acceptRequestInstances) { LifeCycleMethods methods = methodsMap.get(obj.getClass()); startInstance(obj, methods.methodsFor(AcceptRequests.class)); if (!methods.hasFor(PreDestroy.class)) { acceptRequestInstances.remove(obj); } } for (Object obj : managedInstances) { LifeCycleMethods methods = methodsMap.get(obj.getClass()); if (!methods.hasFor(PreDestroy.class)) { managedInstances.remove(obj); } } Thread thread = new Thread(() -> { try { LifeCycleManager.this.stop(); } catch (Exception e) { log.error(e, "Trying to shut down"); } }); Runtime.getRuntime().addShutdownHook(thread); Logging.addShutdownLatchToWaitFor(stoppedLatch); state.set(State.STARTED); log.info("Life cycle startup complete. System ready."); } LifeCycleManager(List<Object> managedInstances, @Nullable LifeCycleMethodsMap methodsMap, LifeCycleConfig config); int size(); void start(); void stop(); void addInstance(Object instance);  }
@Test public void testImmediateStarts() throws Exception { Injector injector = Guice.createInjector( Stage.PRODUCTION, new LifeCycleModule(), binder -> { initializeConfig(binder); binder.bind(InstanceThatRequiresStart.class).in(Scopes.SINGLETON); binder.bind(InstanceThatUsesInstanceThatRequiresStart.class).in(Scopes.SINGLETON); } ); LifeCycleManager lifeCycleManager = injector.getInstance(LifeCycleManager.class); lifeCycleManager.start(); assertEquals(stateLog, ImmutableList.of("InstanceThatUsesInstanceThatRequiresStart:OK")); }