pf4j 默认系统扩展以及机制说明

pf4j 支持直接在应用中进行插件的开发以及运行(不需要复杂的处理)
与serviceloader 比较类似,我么只需要添加一个注解就可以了(@Extension)

参考运行

 
public static void main(String[] args) {
    PluginManager pluginManager = new DefaultPluginManager();
   //  pluginManager.loadPlugins();
   // pluginManager.startPlugins();
    List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
    for (Greeting greeting : greetings) {
        System.out.println(">>> " + greeting.getGreeting());
    }
}

实现原理

主要是 DefaultPluginManager 的默认实现,包含的一个createExtensionFinder方法

@Override
protected ExtensionFinder createExtensionFinder() {
    DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this);
    addPluginStateListener(extensionFinder);
 
    return extensionFinder;
}

默认实现的处理,添加了一个自己的LegacyExtensionFinder

public DefaultExtensionFinder(PluginManager pluginManager) {
    this.pluginManager = pluginManager;
   // 添加默认的LegacyExtensionFinder 
    add(new LegacyExtensionFinder(pluginManager));
//        add(new ServiceProviderExtensionFinder(pluginManager));
}

LegacyExtensionFinder class 查找处理,使用了基类的 AbstractExtensionFinder.java

private Map<String, Set<String>> readStorages() {
        Map<String, Set<String>> result = new LinkedHashMap<>();
 
        result.putAll(readClasspathStorages());
        result.putAll(readPluginsStorages());
 
        return result;
}

LegacyExtensionFinder readClasspathStorages 实现处理,先直接查询的classpath,就能确保使用应用的扩展接口

public Map<String, Set<String>> readClasspathStorages() {
    log.debug("Reading extensions storages from classpath");
    Map<String, Set<String>> result = new LinkedHashMap<>();
 
    Set<String> bucket = new HashSet<>();
    try {
        Enumeration<URL> urls = getClass().getClassLoader().getResources(EXTENSIONS_RESOURCE);
        if (urls.hasMoreElements()) {
            collectExtensions(urls, bucket);
        } else {
            log.debug("Cannot find '{}'", EXTENSIONS_RESOURCE);
        }
 
        debugExtensions(bucket);
 
        result.put(null, bucket);
    } catch (IOException e) {
        log.error(e.getMessage(), e);
    }
 
    return result;
}

参考资料

https://pf4j.org/doc/system-extension.html

上一篇:嵌入式C学习笔记1


下一篇:二叉树的前、中、后序遍历