src/main/java/js/container/Container.java
public void destroy() {
		log.trace("destroy()");

		// cron manager should be destroyed first to avoid invoking cron methods on cleaned managed instance
		cronManager.destroy();

		// classes pool is not sorted; it is a hash map for performance reasons
		// also, a managed class may appear multiple times if have multiple interfaces
		// bellow sorted set is used to ensure reverse order on managed classes destruction
		// comparison is based on managed class key that is created incrementally

		Set<ManagedClassSPI> sortedClasses = new TreeSet<>(new Comparator<ManagedClassSPI>() {
			@Override
			public int compare(ManagedClassSPI o1, ManagedClassSPI o2) {
				// compare second with first to ensure descending sorting
				return o2.getKey().compareTo(o1.getKey());
			}
		});

		for (ManagedClassSPI managedClass : classesPool.values()) {
			// process only implementations of managed pre-destroy interface
			if (Types.isKindOf(managedClass.getImplementationClass(), ManagedPreDestroy.class)) {
				sortedClasses.add(managedClass);
			}
		}

		for (ManagedClassSPI managedClass : sortedClasses) {
			ScopeFactory scopeFactory = scopeFactories.get(managedClass.getInstanceScope());
			InstanceKey instanceKey = new InstanceKey(managedClass.getKey());
			Object instance = scopeFactory.getInstance(instanceKey);
			if (instance == null) {
				continue;
			}

			// sorted managed classes contains only implementations of pre-destroy interface
			// in case instance is a Java Proxy takes care to execute pre-destroy hook on wrapped instance
			// in order to avoid adding container services to this finalization hook
			ManagedPreDestroy managedInstance = (ManagedPreDestroy) Classes.unproxy(instance);
			log.debug("Pre-destroy managed instance |%s|.", managedInstance.getClass());
			try {
				managedInstance.preDestroy();
			} catch (Throwable t) {
				log.dump(String.format("Managed instance |%s| pre-destroy fail:", instance.getClass()), t);
			}
		}

		for (ScopeFactory scopeFactory : scopeFactories.values()) {
			// local scope has null factory
			if (scopeFactory != null) {
				scopeFactory.clear();
			}
		}

		classesPool.clear();
		instanceProcessors.clear();
		scopeFactories.clear();
		instanceFactories.clear();
	}
public void destroy() {
		log.trace("destroy()");

		// cron manager should be destroyed first to avoid invoking cron methods on cleaned managed instance
		cronManager.destroy();

		// classes pool is not sorted; it is a hash map for performance reasons
		// also, a managed class may appear multiple times if have multiple interfaces
		// bellow sorted set is used to ensure reverse order on managed classes destruction
		// comparison is based on managed class key that is created incrementally

		Set<ManagedClassSPI> sortedClasses = new TreeSet<>(new Comparator<ManagedClassSPI>() {
			@Override
			public int compare(ManagedClassSPI o1, ManagedClassSPI o2) {
				// compare second with first to ensure descending sorting
				return o2.getKey().compareTo(o1.getKey());
			}
		});

		for (ManagedClassSPI managedClass : classesPool.values()) {
			// process only implementations of managed pre-destroy interface
			if (Types.isKindOf(managedClass.getImplementationClass(), ManagedPreDestroy.class)) {
				sortedClasses.add(managedClass);
			}
		}

		for (ManagedClassSPI managedClass : sortedClasses) {
			ScopeFactory scopeFactory = scopeFactories.get(managedClass.getInstanceScope());
			InstanceKey instanceKey = new InstanceKey(managedClass.getKey());
			Object instance = scopeFactory.getInstance(instanceKey);
			if (instance == null) {
				continue;
			}

			// sorted managed classes contains only implementations of pre-destroy interface
			// in case instance is a Java Proxy takes care to execute pre-destroy hook on wrapped instance
			// in order to avoid adding container services to this finalization hook
			ManagedPreDestroy managedInstance = (ManagedPreDestroy) Classes.unproxy(instance);
			log.debug("Pre-destroy managed instance |%s|.", managedInstance.getClass());
			try {
				managedInstance.preDestroy();
			} catch (Throwable t) {
				log.dump(String.format("Managed instance |%s| pre-destroy fail:", instance.getClass()), t);
			}
		}

		for (ScopeFactory scopeFactory : scopeFactories.values()) {
			// local scope has null factory
			if (scopeFactory != null) {
				scopeFactory.clear();
			}
		}

		classesPool.clear();
		instanceProcessors.clear();
		scopeFactories.clear();
		instanceFactories.clear();
	}
public void destroy ( ) { log . trace ( "destroy()" ) ; // cron manager should be destroyed first to avoid invoking cron methods on cleaned managed instance
 cronManager . destroy ( ) ; // classes pool is not sorted; it is a hash map for performance reasons
 // also, a managed class may appear multiple times if have multiple interfaces
 // bellow sorted set is used to ensure reverse order on managed classes destruction
 // comparison is based on managed class key that is created incrementally
 Set < ManagedClassSPI > sortedClasses = new TreeSet <> ( new Comparator < ManagedClassSPI > ( ) { @ Override public int compare ( ManagedClassSPI o1 , ManagedClassSPI o2 ) { // compare second with first to ensure descending sorting
 return o2 . getKey ( ) . compareTo ( o1 . getKey ( ) ) ; } } ) ; for ( ManagedClassSPI managedClass : classesPool . values ( ) ) { // process only implementations of managed pre-destroy interface
 if ( Types . isKindOf ( managedClass . getImplementationClass ( ) , ManagedPreDestroy . class ) ) { sortedClasses . add ( managedClass ) ; } } for ( ManagedClassSPI managedClass : sortedClasses ) { ScopeFactory scopeFactory = scopeFactories . get ( managedClass . getInstanceScope ( ) ) ; InstanceKey instanceKey = new InstanceKey ( managedClass . getKey ( ) ) ; Object instance = scopeFactory . getInstance ( instanceKey ) ; if ( instance == null ) { continue ; } // sorted managed classes contains only implementations of pre-destroy interface
 // in case instance is a Java Proxy takes care to execute pre-destroy hook on wrapped instance
 // in order to avoid adding container services to this finalization hook
 ManagedPreDestroy managedInstance = ( ManagedPreDestroy ) Classes . unproxy ( instance ) ; log . debug ( "Pre-destroy managed instance |%s|." , managedInstance . getClass ( ) ) ; try { managedInstance . preDestroy ( ) ; } catch ( Throwable t ) { log . dump ( String . format ( "Managed instance |%s| pre-destroy fail:" , instance . getClass ( ) ) , t ) ; } } for ( ScopeFactory scopeFactory : scopeFactories . values ( ) ) { // local scope has null factory
 if ( scopeFactory != null ) { scopeFactory . clear ( ) ; } } classesPool . clear ( ) ; instanceProcessors . clear ( ) ; scopeFactories . clear ( ) ; instanceFactories . clear ( ) ; }
Destroy container and release caches, factories and processors. This is container global clean-up invoked at application
unload; after executing this method no managed instance can be created or reused. Attempting to use {@link AppFactory}
after container destroy may lead to not predictable behavior.
<p>
Before caches clean-up, this method invokes {@link ManagedPreDestroy} on all managed instances that are active, that is,
cached in all scope factories. Takes care to execute pre-destroy in reverse order from application descriptor
declarations. This ensure {@link App} is destroyed last since App class descriptor is declared first into application
descriptor.
Destroy container and release caches factories and processors . This is container global clean - up invoked at application unload ; after executing this method no managed instance can be created or reused . Attempting to use {