InjectorImpl implements Injector { @Override public void stop() { final AtomicBoolean hasAnythingChanged = new AtomicBoolean(); final ClassMapper classMapper = this::findRequired; Set<DependencyNode> unfinished; while (!(unfinished = graph.nodes() .filter(n -> n.getCurrentState() != State.STOPPED) .collect(toSet())).isEmpty()) { hasAnythingChanged.set(false); unfinished.forEach(n -> stop(hasAnythingChanged, classMapper, n)); if (!hasAnythingChanged.get()) { throw new IllegalStateException( "Injector appears to be stuck in an infinite loop. The " + "following components have not been stopped: " + unfinished.stream() .map(DependencyNode::getRepresentedType) .map(Class::getSimpleName) .collect(toSet()) ); } } LOGGER_INSTANCE.debug(HORIZONTAL_LINE); LOGGER_INSTANCE.debug( "| %-79s |", "All " + instances.size() + " components have been stopped!" ); LOGGER_INSTANCE.debug(HORIZONTAL_LINE); } InjectorImpl(
        final Set<Injectable<?>> injectables,
        final List<Object> instances,
        final Properties properties,
        final ClassLoader classLoader,
        final DependencyGraph graph,
        final InjectorBuilder builder
    ); static InjectorBuilder builder(); static InjectorBuilder builder(ClassLoader classLoader); @Override Stream<T> stream(Class<T> type); @Override T getOrThrow(Class<T> type); @Override T getAfterOrThrow(Class<T> type, T before); @Override Optional<T> get(Class<T> type); @Override Optional<T> getAfter(Class<T> type, T before); @Override Stream<Class<?>> injectables(); @Override T inject(T instance); @Override ClassLoader classLoader(); @Override void stop(); @Override InjectorBuilder newBuilder(); static final Logger LOGGER_INSTANCE; }
@Test void stop() { final Logger logger = LoggerManager.getLogger(InjectorImpl.class); final Level level = logger.getLevel(); logger.setLevel(Level.DEBUG); try { final Baz baz = injector.getOrThrow(Baz.class); injector.stop(); assertTrue(baz.stopped); } finally { logger.setLevel(level); } }