Golang 插件化开发
Golang官方提供了plugin
模块,该模块可以支持插件开发.
目前很多思路都是在开发过程中支持插件话,当主体程序写完后,不能够临时绑定插件.但是本文将带领你进行主体程序自动识别并加载、控制插件调用.
代码地址: https://github.com/A-Donga/PluginTest
文章目录
基本思路
插件化开发中,一定存在一个主体程序,对其他插件进行控制、处理、调度.
具有模拟业务的主体程序
我们首先开发一个简单的业务程序,进行两种输出.
- 当时间秒数为
奇数
的时候,输出hello
- 当时间秒数为
偶数
的时候,输出world
主体代码
代码有一定的冗余,是为了模拟业务之间的调度
主文件名:MainFile.go
package main
import (
"fmt"
"time"
)
/*
@author: mxd
@create time: 2020/10/5
*/
// main 主体程序入口
func main() {
// time.Now().Second 将会返回当前秒数
nowSecond := time.Now().Second()
doPrint(nowSecond)
fmt.Println("Process Stop ========")
}
// 执行打印操作
func doPrint(nowSecond int) {
if nowSecond%2 == 0 {
printWorld() //偶数
} else {
printHello() //奇数
}
}
// 执行打印hello
func printHello() {
fmt.Println("hello")
}
// 执行打印world
func printWorld() {
fmt.Println("world")
}
// init 函数将于 main 函数之前运行
func init() {
fmt.Println("Process On ==========")
}
输出如下:
简单的插件
然后我们编写一个插件代码
插件代码的入口package
也要为main
,但是可以不包含main
方法
设定插件逻辑为当当前秒数为奇数的时候,同时输出当前时间(与hello的判定不是一个时间)
插件文件名:HelloPlugin.go
插件代码
package main
import (
"fmt"
"time"
)
/*
@author: mxd
@create time: 2020/10/5
*/
// 打印当前时间
func PrintNowTime(){
fmt.Println(time.Now().Second())
}
在当前目录下,执行插件生成指令:
$ go build --buildmode=plugin -o HelloPlugin.so HelloPlugin.go
当前目录下就会多出来一个文件HelloPlugin.so
然后,我们让主程序加载该插件
修改的主体代码
package main
import (
"fmt"
"plugin"
"time"
)
/*
@author: mxd
@create time: 2020/10/5
*/
// main 主体程序入口
func main() {
// time.Now().Second 将会返回当前秒数
nowSecond := time.Now().Second()
doPrint(nowSecond)
fmt.Println("Process Stop ========")
}
// 执行打印操作
func doPrint(nowSecond int) {
if nowSecond%2 == 0 {
printWorld() //偶数
} else {
printHello() //奇数
}
}
// 执行打印hello
func printHello() {
// 执行插件调用
if pluginFunc != nil{
//将存储的信息转换为函数
if targetFunc, ok := pluginFunc.(func()); ok {
targetFunc()
}
}
fmt.Println("hello")
}
// 执行打印world
func printWorld() {
fmt.Println("world")
}
// 定义插件信息
const pluginFile = "HelloPlugin.so"
// 存储插件中将要被调用的方法或变量
var pluginFunc plugin.Symbol
// init 函数将于 main 函数之前运行
func init() {
// 查找插件文件
pluginFile, err := plugin.Open(pluginFile)
if err != nil {
fmt.Println("An error occurred while opening the plug-in")
} else{
// 查找目标函数
targetFunc, err