public void destroy() {
        final Map<String, Object> immutableObjects = Collections.unmodifiableMap(objects);

        //destroy objects in the opposite order they were initialized:
        List<Map.Entry<String, ?>> entries = new ArrayList<Map.Entry<String, ?>>(objects.entrySet());
        Collections.reverse(entries);

        for (Map.Entry<String, ?> entry : entries) {
            String id = entry.getKey();
            Object bean = entry.getValue();

            //don't destroy the eventbus until the end - we need it to still be 'alive' while publishing destroy events:
            //memory equality check (not .equals) on purpose
            if (bean != this.eventBus) {
                LifecycleUtils.destroy(bean);
                BeanEvent event = new DestroyedBeanEvent(id, bean, immutableObjects);
                eventBus.publish(event);
                //bean is now destroyed - it should not receive any other events
                this.eventBus.unregister(bean);
            }
        }
        //only now destroy the event bus:
        LifecycleUtils.destroy(this.eventBus);
    }
Plug in another way to get objects into configuration, ex: CDI

@param alternateObjectSupplier not null (empty lambda ok)
@since 2.0
config/ogdl/src/main/java/org/apache/shiro/config/ogdl/ReflectionBuilder.java