EmbeddableComponentManager implements NamespacedComponentManager, Disposable { @Override public void dispose() { List<RoleHint<?>> keys = new ArrayList<>(this.componentEntries.size() * 2); for (Map<String, ComponentEntry<?>> entries : this.componentEntries.values()) { for (ComponentEntry<?> entry : entries.values()) { addForDisposalReversedOrder(entry, keys); } } Collections.reverse(keys); RoleHint<ComponentManager> cmRoleHint = new RoleHint<>(ComponentManager.class); ComponentEntry<?> cmEntry = getComponentEntry(cmRoleHint.getRoleType(), cmRoleHint.getHint()); if (cmEntry != null && cmEntry.instance == this) { cmEntry.disposing = false; keys.remove(cmRoleHint); } Collections.sort(keys, new Comparator<RoleHint<?>>() { @Override public int compare(RoleHint<?> rh1, RoleHint<?> rh2) { return getPriority(rh1) - getPriority(rh2); } private int getPriority(RoleHint<?> rh) { Object instance = getComponentEntry(rh.getRoleType(), rh.getHint()).instance; if (instance == null) { return DisposePriority.DEFAULT_PRIORITY; } else { DisposePriority priorityAnnotation = instance.getClass().getAnnotation(DisposePriority.class); return (priorityAnnotation == null) ? DisposePriority.DEFAULT_PRIORITY : priorityAnnotation.value(); } } }); for (RoleHint<?> key : keys) { ComponentEntry<?> componentEntry = getComponentEntry(key.getRoleType(), key.getHint()); synchronized (componentEntry) { Object instance = componentEntry.instance; if (instance instanceof Disposable && componentEntry.instance != this) { try { SHUTDOWN_LOGGER.debug("Disposing component [{}]...", instance.getClass().getName()); ((Disposable) instance).dispose(); SHUTDOWN_LOGGER.debug("Component [{}] has been disposed", instance.getClass().getName()); } catch (ComponentLifecycleException e) { this.logger.error("Failed to dispose component with role type [{}] and role hint [{}]", componentEntry.descriptor.getRoleType(), componentEntry.descriptor.getRoleHint(), e); } } } } for (RoleHint<?> key : keys) { this.componentEntries.get(key.getRoleType()).remove(key.getHint()); } } EmbeddableComponentManager();  EmbeddableComponentManager(String namespace); @Override String getNamespace(); void initialize(ClassLoader classLoader); @Override boolean hasComponent(Type role); @Override boolean hasComponent(Type roleType, String roleHint); @Override T getInstance(Type roleType); @Override T getInstance(Type roleType, String roleHint); @Override List<T> getInstanceList(Type role); @Override @SuppressWarnings("unchecked") Map<String, T> getInstanceMap(Type roleType); @Override @SuppressWarnings("unchecked") ComponentDescriptor<T> getComponentDescriptor(Type role, String hint); @Override @SuppressWarnings("unchecked") List<ComponentDescriptor<T>> getComponentDescriptorList(Type role); @Override ComponentEventManager getComponentEventManager(); @Override void setComponentEventManager(ComponentEventManager eventManager); @Override ComponentManager getParent(); @Override void setParent(ComponentManager parentComponentManager); @Override void registerComponent(ComponentDescriptor<T> componentDescriptor); @Override void registerComponent(ComponentDescriptor<T> componentDescriptor, T componentInstance); @Override void unregisterComponent(Type role, String hint); @Override void unregisterComponent(ComponentDescriptor<?> componentDescriptor); @Override void release(Object component); @Override void dispose(); @Override @Deprecated List<ComponentDescriptor<T>> getComponentDescriptorList(Class<T> role);  }
@Test void dispose() throws Exception { EmbeddableComponentManager ecm = new EmbeddableComponentManager(); DefaultComponentDescriptor<Role> cd1 = new DefaultComponentDescriptor<>(); cd1.setRoleType(Role.class); cd1.setRoleHint("instance1"); cd1.setImplementation(DisposableWithPriorityRoleImpl.class); cd1.setInstantiationStrategy(ComponentInstantiationStrategy.SINGLETON); ecm.registerComponent(cd1); DisposableWithPriorityRoleImpl instance1 = ecm.getInstance(Role.class, "instance1"); DefaultComponentDescriptor<Role> cd2 = new DefaultComponentDescriptor<>(); cd2.setRoleType(Role.class); cd2.setRoleHint("instance2"); cd2.setImplementation(DisposableRoleImpl.class); cd2.setInstantiationStrategy(ComponentInstantiationStrategy.SINGLETON); ecm.registerComponent(cd2); DisposableRoleImpl instance2 = ecm.getInstance(Role.class, "instance2"); assertFalse(instance1.isFinalized()); assertFalse(instance2.isFinalized()); ecm.dispose(); assertTrue(instance1.isFinalized()); assertTrue(instance2.isFinalized()); assertNull(ecm.getComponentDescriptor(Role.class, "instance1")); assertNull(ecm.getComponentDescriptor(Role.class, "instance2")); assertNotNull(ecm.getComponentDescriptor(ComponentManager.class, "default")); assertEquals("DisposableWithPriorityRoleImpl", lastDisposedComponent); }