iocli 工具
iocli 源码位于 github.com/alibaba/IOC-golang/iocli ,是一款命令行工具,提供了以下能力:
代码调试
开发者可以使用 iocli 作为调试客户端,调试基于 ioc-golang 框架开发的 go 应用程序。
结构相关代码生成
开发者可以为需要依赖注入的结构体增加注解,iocli 会识别这些注解,并产生符合要求的结构相关代码。包括结构描述信息、结构代理层、结构专属接口、结构 Get 方法等。
调试能力
ioc-golang 框架拥有基于 AOP 的 Go 运行时程序调试能力,帮助故障排查,性能分析,提高应用可观测能力。在 快速开始 部分展示了接口信息的查看、参数监听能力。在 基于 IOC-golang 的电商系统demo 中,可以展示基于 ioc-golang 的,业务无侵入的,方法粒度全链路追踪能力。
注解与代码生成
注解 是以特定字符串开头的注释,标注在期望注入的结构前。注解 只具备静态意义,即在代码生成阶段,被 iocl i工具扫描识别到,从而获取结构相关信息。注解 本身不具备程序运行时的意义。
iocli 可以识别以下注解 key,其中 = 后面的 value 为示例。
// +ioc:autowire=true
// +ioc:autowire:type=normal
// +ioc:autowire:paramLoader=paramLoader
// +ioc:autowire:paramType=Config
// +ioc:autowire:constructFunc=New
// +ioc:autowire:baseType=true
// +ioc:autowire:alias=MyAppAlias
// +ioc:tx:func=MyTransactionFunction
ioc:autowire (必填)
bool 类型,为 true 则在代码生成阶段被识别到。
ioc:autowire:type (必填)
string类型,表示依赖注入模型,目前支持以下五种,结构提供者可以选择五种中的一种或多种进行标注,从而生成相关的结构信息与 API,供结构使用者选用。
// +ioc:autowire:type=singleton // +ioc:autowire:type=normal type MyStruct struct{ }
singleton
单例模型,使用该注入模型获取到的结构体,全局只存在一个对象。
normal
多例模型,使用该注入模型,每一个标签注入字段、每一次 API 获取,都会产生一个新的对象。
config:
配置模型是基于多例模型的封装扩展,基于配置模型定义的结构体方便从 yaml 配置文件中注入信息。参考例子 example/autowire/autowire_config
grpc:
grpc 模型是基于单例模型的封装扩展,基于 grpc 模型可以方便地从 yaml 配置文件中读取参数,生成 grpc 客户端。参考例子 example/third_party/autowire/grpc
rpc:
rpc 模型会在代码生成阶段产生 rpc 服务端注册代码,以及 rpc 客户端调用存根。参考例子 example/autowire/autowire_rpc
ioc:autowire:paramLoader(非必填)
string类型,表示需要定制的“参数加载器“类型名
参数加载器由结构定义者可选定制。可参考:extension/state/redis
参数加载器需要实现Load方法:
// ParamLoader is interface to load param type ParamLoader interface { Load(sd *StructDescriptor, fi *FieldInfo) (interface{}, error) }
定义结构的开发者可以通过实现参数加载器,来定义自己的结构初始化参数。例如,一个 redis 客户端结构 ‘Impl’,需要从Config 参数来加载,如下所示 New 方法。
type Config struct { Address string Password string DB string } func (c *Config) New(impl *Impl) (*Impl, error) { dbInt, err := strconv.Atoi(c.DB) if err != nil { return impl, err } client := redis.NewClient(&redis.Options{ Addr: c.Address, Password: c.Password, DB: dbInt, }) _, err = client.Ping().Result() if err != nil { return impl, err } impl.client = client return impl, nil }
Config 包含的三个字段:Address Password DB,需要由使用者传入。
从哪里传入?这就是参数加载器所做的事情。
结构定义者可以定义如下加载器,从而将字段通过注入该结构的 tag 标签获取,如果tag信息标注了配置位置,则通过配置文件获取。
type paramLoader struct { } func (p *paramLoader) Load(sd *autowire.StructDescriptor, fi *autowire.FieldInfo) (interface{}, error) { splitedTagValue := strings.Split(fi.TagValue, ",") param := &Config{} if len(splitedTagValue) == 1 { return nil, fmt.Errorf("file info %s doesn't contain param infomration, create param from sd paramLoader failed", fi) } if err := config.LoadConfigByPrefix("extension.normal.redis."+splitedTagValue[1], param); err != nil { return nil, err } return param, nil }
例如
type App struct { NormalDB3Redis normalRedis.Redis `normal:"github.com/alibaba/ioc-golang/extension/state/redis.Redis,address=127.0.0.1:6379&db=3"` }
当然也可以从配置文件读入,tag中指定了key为 db1-redis
type App struct { NormalDB3Redis normalRedis.Redis `normal:"github.com/alibaba/ioc-golang/extension/state/redis.Redis,db1-redis"` }
ioc-go.yaml: autowire.normal.Redis.Impl.db1-redis.param 读入参数
autowire: normal: github.com/alibaba/ioc-golang/extension/state/redis.Redis: db1-redis: param: address: localhost:6379 db: 1
我们提供了预置的参数加载器
除非用户有强烈需求,我们更推荐用户直接使用我们预置的参数加载器:http://github.com/alibaba/ioc-golang/tree/master/autowire/param_loader。
我们会先后尝试:标签重定向到配置、标签读入参数、配置文件的默认位置读入参数。每个注册到框架的结构都有唯一的ID,因此也会在配置文件中拥有配置参数的位置,这一默认位置在这里定义:http://github.com/alibaba/ioc-golang/blob/master/autowire/param_loader/default_config.go#L21,我们更希望和用户约定好这一点。
当所有加载器都加载参数失败后,将会抛出错误。使用者应当查阅自己引入的结构加载器实现,并按照要求配置好参数。
ioc:autowire:paramType(非必填)
string类型,表示依赖参数的类型名,在上述例子,该类型名为 Config
ioc:autowire:constructFunc(非必填)
string类型,表示结构的构造方法名
在给出 ioc:autowire:paramType 参数类型名的情况下,会使用参数的函数作为构造函数,例如在上述例子中,该构造方法为 Config 对象的 New 方法。
如果没有给出 ioc:autowire:paramType 参数类型名,则会直接使用这一方法作为构造函数。
我们要求该构造方法的函数签名是固定的,即:
func (*$(结构名)) (*$(结构名), error)
ioc:autowire:baseType=true (非必填)
该类型是否为基础类型
go 基础类型不可直接通过&在构造时取地址,因此我们针对基础类型单独设计了该注解。在 配置扩展 中被使用较多。
ioc:autowire:alias=MyAppAlias (非必填)
该类型的别名,可在标签、API获取、配置中,通过该别名替代掉较长的类型全名来指定结构。
ioc:tx:func=MyTransactionFunction(非必填)
指定事务函数和回滚函数,参考事务例子 example/aop/transaction
iocli 操作命令
iocli init
生成初始化工程
iocli gen
递归遍历当前目录下的所有 go pkg ,根据注解生成结构体相关代码。
iocli list
查看应用所有接口和方法信息,默认端口 :1999
iocli watch [structID] [methodName]
监听一个方法的实时调用信息
iocli monitor [structID] [methodName]
开启调用监控,structID 和 methodName 可不指定,则监控所有接口方法。
iocli trace [structID] [methodName]
以当前方法为入口,开启调用链路追踪
具体操作参数可通过 -h 查看。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.