ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pf4j 插件加载机制

2022-02-16 19:35:48  阅读:236  来源: 互联网

标签:插件 log plugin pf4j pluginId pluginPath plugins 加载


主要简单说明下pf4j 的插件加载处理
参考代码 pf4j/src/main/java/org/pf4j/AbstractPluginManager.java

加载代码

  • loadPlugins 处理
 
    加载处理
    @Override
    public void loadPlugins() {
        log.debug("Lookup plugins in '{}'", pluginsRoots);
        // check for plugins roots
        if (pluginsRoots.isEmpty()) {
            log.warn("No plugins roots configured");
            return;
        }
        pluginsRoots.forEach(path -> {
            if (Files.notExists(path) || !Files.isDirectory(path)) {
                log.warn("No '{}' root", path);
            }
        });
 
        // get all plugin paths from repository
        // 查找路径
        List<Path> pluginPaths = pluginRepository.getPluginPaths();
 
        // check for no plugins
        if (pluginPaths.isEmpty()) {
            log.info("No plugins");
            return;
        }
 
        log.debug("Found {} possible plugins: {}", pluginPaths.size(), pluginPaths);
 
        // load plugins from plugin paths
        for (Path pluginPath : pluginPaths) {
            try {
                // 加载发现到的插件,此方法比较重要
                loadPluginFromPath(pluginPath);
            } catch (PluginRuntimeException e) {
                log.error(e.getMessage(), e);
            }
        }
 
        // resolve plugins
        try {
           // 解析插件,主要是关于依赖,解析插件描述信息,然后进行插件状态的通知
            resolvePlugins();
        } catch (PluginRuntimeException e) {
            log.error(e.getMessage(), e);
        }
    }
  • loadPluginFromPath 方法
    此方法比较重要,进行了插件的查找以及插件的classloader创建,形成一个插件的基本存储,方便后续流程使用
    PluginWrapper 是一个比较重要的实体,包含了不少关于插件的元数据信息
 
 protected PluginWrapper loadPluginFromPath(Path pluginPath) {
        // Test for plugin path duplication
        String pluginId = idForPath(pluginPath);
        if (pluginId != null) {
            throw new PluginAlreadyLoadedException(pluginId, pluginPath);
        }
 
        // Retrieve and validate the plugin descriptor
        PluginDescriptorFinder pluginDescriptorFinder = getPluginDescriptorFinder();
        log.debug("Use '{}' to find plugins descriptors", pluginDescriptorFinder);
        log.debug("Finding plugin descriptor for plugin '{}'", pluginPath);
        PluginDescriptor pluginDescriptor = pluginDescriptorFinder.find(pluginPath);
        validatePluginDescriptor(pluginDescriptor);
 
        // Check there are no loaded plugins with the retrieved id
        pluginId = pluginDescriptor.getPluginId();
        if (plugins.containsKey(pluginId)) {
            PluginWrapper loadedPlugin = getPlugin(pluginId);
            throw new PluginRuntimeException("There is an already loaded plugin ({}) "
                    + "with the same id ({}) as the plugin at path '{}'. Simultaneous loading "
                    + "of plugins with the same PluginId is not currently supported.\n"
                    + "As a workaround you may include PluginVersion and PluginProvider "
                    + "in PluginId.",
                loadedPlugin, pluginId, pluginPath);
        }
 
        log.debug("Found descriptor {}", pluginDescriptor);
        String pluginClassName = pluginDescriptor.getPluginClass();
        log.debug("Class '{}' for plugin '{}'",  pluginClassName, pluginPath);
 
        // load plugin
        log.debug("Loading plugin '{}'", pluginPath);
        // 此处,保证每个插件会有一个不同的classloader,这个后续会介绍
        ClassLoader pluginClassLoader = getPluginLoader().loadPlugin(pluginPath, pluginDescriptor);
        log.debug("Loaded plugin '{}' with class loader '{}'", pluginPath, pluginClassLoader);
 
        PluginWrapper pluginWrapper = createPluginWrapper(pluginDescriptor, pluginPath, pluginClassLoader);
 
        // test for disabled plugin
        if (isPluginDisabled(pluginDescriptor.getPluginId())) {
            log.info("Plugin '{}' is disabled", pluginPath);
            pluginWrapper.setPluginState(PluginState.DISABLED);
        }
 
        // validate the plugin
        if (!isPluginValid(pluginWrapper)) {
            log.warn("Plugin '{}' is invalid and it will be disabled", pluginPath);
            pluginWrapper.setPluginState(PluginState.DISABLED);
        }
 
        log.debug("Created wrapper '{}' for plugin '{}'", pluginWrapper, pluginPath);
 
        pluginId = pluginDescriptor.getPluginId();
 
        // add plugin to the list with plugins
        plugins.put(pluginId, pluginWrapper);
        getUnresolvedPlugins().add(pluginWrapper);
 
        // add plugin class loader to the list with class loaders
        getPluginClassLoaders().put(pluginId, pluginClassLoader);
 
        return pluginWrapper;
    }

说明

以上是关于pf4j 插件加载的简单说明,实际上pf4j还包含插件的unload start stop。。。后续会介绍

参考资料

https://pf4j.org/doc/plugin-lifecycle.html
https://pf4j.org/doc/plugins.html

标签:插件,log,plugin,pf4j,pluginId,pluginPath,plugins,加载
来源: https://www.cnblogs.com/rongfengliang/p/15902003.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有