Go1.8之后支持插件机制,能够动态加载代码。Grafana是开源可视化监控平台,后端是用Go语言编写的,是非常流行的Go语言开源项目,该项目也是基于插件机制,让用户可以下载安装相应的数据库插件。本文介绍插件机制及平台支持情况,如何创建、构建应用以及如何加载插件。

插件机制

Go插件能用于很多场景,基于插件可以把系统分解为通用引擎,容易独立开发和测试。插件都遵循严格接口规范,职责明确。程序可以使用不同插件进行组合,甚至同时使用同一插件的不同版本。主程序和插件之间清晰的界限促进了松耦合和关注点分离。

Go1.8引入新的"plugin"包,提供了Open函数加载共享库返回Plugin对象。插件对象有Lookup函数返回Symbol(interface{}),它可以对插件暴露的函数或变量进行类型断言。官方文档描述Symbol:A Symbol is a pointer to a variable or function.

插件包目前仅支持Linux系统,对于其他OS需要通过其他方式进行实现,官方文档描述如下:

Currently plugins are only supported on Linux, FreeBSD, and macOS. Please report any issues.

插件示例

Go插件与正常包一样,也可以像正常包一样使用它,仅当把它编译为插件才会成为插件。

创建插件

下面实现一个简单功能插件,并在应用中调用其他暴露方法。

package mainimport "fmt"var V intfunc F() { fmt.Printf("Hello, number %d\n", V)
}

非常简单,与正常代码一样,这里暴露了变量V和F()函数。

下面要编译为插件,需要使用-buildmode=plugin选项,并指定名称为typ_plugin.so,放在上级目录,为了后面main中调用:

go build -buildmode=plugin -o ../typ_plugin.so

执行命令,需要安装gcc编译环境,正常会在上级目录生成相应typ_plugin.so库文件。

加载插件

加载插件需要知道目标插件的位置(*.so共享库的位置),可以通过下面几种方法实现:

  • 通过命令行参数指定
  • 设置环境变量
  • 使用配置文件
  • 使用已知目录

另一个问题是主程序是否知道插件名称,或者它是否需要动态地发现某个目录下的所有插件。通过filepath.Glob("plugins/*.so")返回所有.so扩展名的插件,然后调用plugin.Open(filename)加载插件,如果有任何错误,程序报错。

在下面的例子中,程序期望在当前工作目录下有一个名为“plugins”的子目录,并加载它找到的所有插件。
下面示例展示如何加载指定目录下所有插件:

package main
import ("fmt""plugin""path/filepath"
)
func main() {all_plugins, err := filepath.Glob("plugins/*.so")if err != nil {panic(err)}for _, filename := range (all_plugins) {fmt.Println(filename)p, err := plugin.Open(filename)if err != nil {panic(err)}}
}

调用插件

定位并加载插件仅完成了一半,插件对象提供了Lookup方法,给定名称返回接口,然后需要类型断言为具体类型。官方文档描述如下:

Lookup searches for a symbol named symName in plugin p. A symbol is any exported variable or function. It reports an error if the symbol is not found. It is safe for concurrent use by multiple goroutines.

简单描述:基于名称进行查找,查找到返回symbol,否则返回错误。插件支持多个协程并发调用。

下面示例首先加载前面创建的插件,然后查找插件中暴露的变量和方法,然后给变量赋值并调用方法。

package mainimport("plugin"
)func main() {p, err := plugin.Open("typ_plugin.so")if err != nil {panic(err)}v, err := p.Lookup("V")if err != nil {panic(err)}f, err := p.Lookup("F")if err != nil {panic(err)}// v执行类型断言,然后取指针,给其赋值*v.(*int) = 8// f推理断言为函数并执行f.(func())()
}

总结

plugin包给编写复杂Go应用提供了很好的机制,通常编程接口很简单,插件可以基于接口有不同复杂实现。应用动态加载插件,让程序更灵活、易扩展。

Golang 插件开发入门教程相关推荐

  1. 【直播回顾】蚂蚁金服高级开发工程师萧恺:IDEA 插件开发入门教程

    主讲人:萧恺(蚂蚁金服-支付宝事业群-高级开发工程师) 本名:肖汉松 讲师介绍: 热爱阅读,喜欢挑战,热衷尝试新的技术,关注技术背后的原理. 关注领域:Java 服务端开发,分布式系统 关注语言:Ja ...

  2. 基于jquery插件开发入门教程

    鉴于最近要使用大量的jquery,所以总有一种捣鼓文字来抒发一下情绪的冲动.思前想后就来篇jquery插件开发入门教程吧,毕竟如果不想开发插件,那自己无论用别人的插件多牛逼,最多只是js的使用者,作为 ...

  3. virtualxposed使用教程_Xposed 插件开发入门教程(一)

    其实网上已经有很多 Xposed 插件开发的入门教程了,我写的这篇与其说是教程,不如说是参考,为了防止以后忘了开发步骤,这里就写篇博客记录一下. 要使用 Xposed 插件,首先要 root 手机并安 ...

  4. chrome插件开发入门教程

    点击上方蓝字"优派编程"选择"加为星标",第一时间关注原创干货 原文地址 http://wp.fang1688.cn/study/539.html 这次我在ch ...

  5. Atom插件开发入门教程(四)

    插件: 修饰文本 上一篇教程,我们已经开发了一个插件.下面我们来看看我们还能做什么.这篇文章会教你如何用一个简单的命令来替换选中的字符串内容.当你选中命令"cool" 时,下面的字 ...

  6. IDEA 插件开发入门教程

    2019独角兽企业重金招聘Python工程师标准>>> IntelliJ IDEA 是目前最好用的 JAVA 开发 IDE,它本身的功能已经非常强大了,但是每个人的需求不一样,有些需 ...

  7. IDEA 插件开发入门教程 1

    IntelliJ IDEA 是目前最好用的 JAVA 开发 IDE,它本身的功能已经非常强大了,但是每个人的需求不一样,有些需求 IDEA 本身无法满足,于是我们就需要自己开发插件来解决.工欲善其事, ...

  8. IntelliJ IDEA插件开发入门教程(一)

    插件开发环境配置 IDEA分为社区版(Community Edition)和旗舰版(Ultimate Edition) 社区版:完全免费,代码开源,但是缺少一些旗舰版中的高级特性. 旗舰版:30天免费 ...

  9. Revit 2021插件开发入门教程

    在这个教程中我们将学习如何开发一个Revit插件,并利用此插件实现设计自动化.课程代码可以从github下载. 第一步是创建 C# Libray新项目,这就是我们的"DeleteDoors& ...

最新文章

  1. android环境安装之android4.2安装(转)
  2. Swift中空合运算符、闭区间运算符、单侧区间、半开区间
  3. (0013)iOS 开发之集成友盟第三方登录
  4. GBRT(GBDT)(MART)(Tree Net)(Tree link)
  5. Atcoder AGC031C Differ By 1 Bit (构造、二进制)
  6. T4 Template Overview
  7. 1818国民经济核算
  8. 广西二级c语言试题,广西区计算机等级考二级C语言笔试试题及答案.doc
  9. php表示昨天_php 获取今日、昨日、上周、本月的起始与结束时间戳
  10. mysql数据库的凭据是什么_使用存储的凭据通过dplyr连接到MySQL数据库
  11. nsis使用URLDownloadToFile下载文件
  12. 2012-11-25 3 00 发喜讯,终于把S5pv210 VGA 分辨率提升到1440 x 900/1920 x 1
  13. iOS逆向工程开发技巧
  14. std::numeric_limits的使用
  15. 废旧的电脑硬盘还可以这样利用起来,太赞了!!
  16. dava靶场远程命令执行
  17. 微信公众号流量主的实际收益(本人亲测)
  18. Apache Kylin在百度地图的实践
  19. 顺丰打印电子运单报500问题解决
  20. 萝卜APP4.30 萝卜APP 追影兔4.30最新开源码

热门文章

  1. 程序员怎样兼职接私活?必看经验之谈
  2. 诚之和:机器人送餐8K超高清直播,5G赋能智慧冬奥
  3. android 图片自动裁剪图片,Android图片选择到裁剪之步步深坑 – 简书
  4. 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛A题Wasserstein Distance
  5. 2016 苹果全球开发者大会(WWDC)
  6. 【WWDC】10分钟带你看完苹果WWDC2022、iOS16、iPadOS16、macOS Ventura、watchOS 9
  7. java 差的绝对值_Java判断绝对值的方法总结
  8. 美国主机BlueHost vs HostEase
  9. windows 下 用 dos 备份 oracle 数据库,并删除七天前的备份
  10. The Trojan War------Greek mythology