ExtensionLoader { public void addListener(ExtensionLoaderListener<T> listener) { synchronized (this) { if (!listeners.contains(listener)) { this.listeners.add(listener); for (ExtensionClass<T> value : all.values()) { try { listener.onLoad(value); } catch (Exception e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Error when notify listener of extensible " + interfaceClass + " with alias: " + value.getAlias() + ".", e); } } } } } } ExtensionLoader(Class<T> interfaceClass, ExtensionLoaderListener<T> listener); protected  ExtensionLoader(Class<T> interfaceClass); protected  ExtensionLoader(Class<T> interfaceClass, boolean autoLoad, ExtensionLoaderListener<T> listener); ConcurrentMap<String, ExtensionClass<T>> getAllExtensions(); ExtensionClass<T> getExtensionClass(String alias); T getExtension(String alias); T getExtension(String alias, Class[] argTypes, Object[] args); void loadExtension(Class loadedClass); void addListener(ExtensionLoaderListener<T> listener);  }
@Test public void testAddListener(){ ExtensionLoader<Filter> extensionLoader = ExtensionLoaderFactory.getExtensionLoader(Filter.class); extensionLoader.loadExtension(DynamicFilter.class); ConcurrentMap<String, ExtensionClass<Filter>> all = extensionLoader.all; String alias = "dynamic0"; Assert.assertTrue(all.containsKey(alias)); List<String> filters = new ArrayList<>(); extensionLoader = ExtensionLoaderFactory.getExtensionLoader(Filter.class); extensionLoader.addListener( new ExtensionLoaderListener<Filter>() { @Override public void onLoad(ExtensionClass<Filter> extensionClass) { filters.add(extensionClass.getAlias()); } }); Assert.assertTrue(filters.contains(alias)); }