当前位置:首页 > 文章列表 > Golang > Go教程 > Golang库插件注册加载机制的问题

Golang库插件注册加载机制的问题

来源:脚本之家 2023-02-16 15:29:31 0浏览 收藏

亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《Golang库插件注册加载机制的问题》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下机制、插件、加载,希望所有认真读完的童鞋们,都有实质性的提高。

最近看到一个内部项目的插件加载机制,非常赞。当然这里说的插件并不是指的golang原生的可以在buildmode中加载指定so文件的那种加载机制。而是软件设计上的「插件」。如果你的软件是一个框架,或者一个平台性产品,想要提升扩展性,即可以让第三方进行第三方库开发,最终能像搭积木一样将这些库组装起来。那么就可能需要这种库加载机制。

我们的目标是什么?对第三方库进行某种库规范,只要按照这种库规范进行开发,这个库就可以被加载到框架中。

我们先定义一个插件的数据结构,这里肯定是需要使用接口来规范,这个可以根据你的项目自由发挥,比如我希望插件有一个Setup方法来在启动的时候加载即可。然后我就定义如下的Plugin结构。

type Plugin interface{
  Name() string
  Setup(config map[string]string) error
}

而在框架启动的时候,我启动了一个如下的全局变量:

var plugins map[string]Plugin

注册

有人可能会问,这里有了加载函数setup,但是为什么没有注册逻辑呢?

答案是注册的逻辑放在库的init函数中。

即框架还提供了一个注册函数。

// package plugin
Register(plugin Plugin)

这个register就是实现了将第三方plugin放到plugins全局变量中。

所以第三方的plugin库大致实现如下:

package MyPlugin

type MyPlugin struct{
}
func (m *MyPlugin) Setup(config map[string]string) error {
	// TODO
func (m *MyPlugin) Name() string {
	return "myPlugin"
func init() {
	plugin.Register(&MyPlugin)

这样注册的逻辑就变成了,如果你要加载一个插件,那么你在main.go中直接以 _ import的形式引入即可。

package main

_ import "github.com/foo/myplugin"
func main() {
}

整体的感觉,这样子插件的注册就被“隐藏”到import中了。

加载

注册的逻辑其实看起来也平平无奇,但是加载的逻辑就考验细节了。

首先插件的加载其实有两点需要考虑:

  • 配置
  • 依赖

配置指的是插件一定是有某种配置的,这些配置以配置文件yaml中plugins.myplugin的路径存在。

plugins:
	myplugin:
		foo: bar

其实我对这种实现持保留意见。配置文件以一个文件中配置项的形式存在,好像不如以配置文件的形式存在,即以config/plugins/myplugin.yaml 的文件。

这样不会出现一个大配置文件的问题。毕竟每个配置文件本身就是一门DSL语言。如果你将配置文件的逻辑变复杂,一定会有很多附带的bug是由于配置文件错误导致的。

第二个说的是依赖。插件A依赖与插件B,那么这里就有加载函数Setup的先后顺序了。这种先后顺序如果纯依赖用户的“经验”,将某个插件的Setup调用放在某个插件的Setup调用之前,是非常痛苦的。(虽然一定是有办法可以做到)。更好的办法是依赖于框架自身的加载机制来进行加载。

首先我们在plugin包中定义一个接口:

type Depend interface{
	DependOn() []string
}

如果我的插件依赖一个名字为 “fooPlugin” 的插件,那么我的插件 MyPlugin就会实现这个接口。

package MyPlugin

type MyPlugin struct{
}
func (m *MyPlugin) Setup(config map[string]string) error {
	// TODO
func (m *MyPlugin) Name() string {
	return "myPlugin"
func init() {
	plugin.Register(&MyPlugin)
func (m *MyPlugin) DependOn() []string {
	return []string{"fooPlugin"}

在最终加载所有插件的时候,我们并不是简单地将所有插件调用Setup,而是使用一个channel,将所有插件放在channel中,然后一个个调用Setup,遇到有Depend其他插件的,且依赖插件还未被加载,则将当前插件放在队列最后(重新塞入channel)。

var setupStatus map[string]bool

// 获取所有注册插件
func loadPlugins() (plugin chan Plugin, setupStatus map[string]bool) {
	// 这里定义一个长度为10的队列
	var sortPlugin = make(chan Plugin, 10)
	var setupStatus = make[string]bool
	
	// 所有的插件
	for name, plugin := range plugins {
		sortPlugin  0 {
		plugin 
<p>上面这段代码最精妙的就是使用了一个有buffer的channel作为一个队列,消费队列一方SetupPlugins,除了消费队列,也有可能生产数据到队列,这样就保证了队列中所有plugin都是被按照标记的依赖被顺序加载的。</p>
<h2>总结</h2>
<p>这种插件的注册和加载机制是非常优雅的。注册方面,巧妙使用隐式import来做插件的注册。而加载方面,巧妙使用有buffer的channel作为加载队列。</p>
<p>今天关于《Golang库插件注册加载机制的问题》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于golang的内容请关注golang学习网公众号!</p>
版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
Go中的gRPC入门教程详解Go中的gRPC入门教程详解
上一篇
Go中的gRPC入门教程详解
简单聊聊Golang中defer预计算参数
下一篇
简单聊聊Golang中defer预计算参数
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    514次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    499次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • SEO  AI Mermaid 流程图:自然语言生成,文本驱动可视化创作
    AI Mermaid流程图
    SEO AI Mermaid 流程图工具:基于 Mermaid 语法,AI 辅助,自然语言生成流程图,提升可视化创作效率,适用于开发者、产品经理、教育工作者。
    645次使用
  • 搜获客笔记生成器:小红书医美爆款内容AI创作神器
    搜获客【笔记生成器】
    搜获客笔记生成器,国内首个聚焦小红书医美垂类的AI文案工具。1500万爆款文案库,行业专属算法,助您高效创作合规、引流的医美笔记,提升运营效率,引爆小红书流量!
    655次使用
  • iTerms:一站式法律AI工作台,智能合同审查起草与法律问答专家
    iTerms
    iTerms是一款专业的一站式法律AI工作台,提供AI合同审查、AI合同起草及AI法律问答服务。通过智能问答、深度思考与联网检索,助您高效检索法律法规与司法判例,告别传统模板,实现合同一键起草与在线编辑,大幅提升法律事务处理效率。
    674次使用
  • TokenPony:AI大模型API聚合平台,一站式接入,高效稳定高性价比
    TokenPony
    TokenPony是讯盟科技旗下的AI大模型聚合API平台。通过统一接口接入DeepSeek、Kimi、Qwen等主流模型,支持1024K超长上下文,实现零配置、免部署、极速响应与高性价比的AI应用开发,助力专业用户轻松构建智能服务。
    740次使用
  • 迅捷AIPPT:AI智能PPT生成器,高效制作专业演示文稿
    迅捷AIPPT
    迅捷AIPPT是一款高效AI智能PPT生成软件,一键智能生成精美演示文稿。内置海量专业模板、多样风格,支持自定义大纲,助您轻松制作高质量PPT,大幅节省时间。
    633次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码