长安链源码学习v2.2.1--ioc机制(十)
前面共同学习长安链ioc如何使用,下面聊聊IOC的实现原理。本节主要分析两个方法,
Register
、Resolve
。
1.func (c *Container) Register(constructor interface{}, options ...Option) error
第一个参数:constructor
,某实现的构造方法,例如:NewFileStore
第二个参数:Option
,例如:Interface
、Parameters
、Default
等,上节有介绍。
1) constructor
参数必须是函数
reflectedResolver := reflect.TypeOf(constructor)if reflectedResolver.Kind() != reflect.Func {return errors.New("container: the constructor must be a function")}
2)创建一个binding
对象,用于设置构造方法 + 默认参数值
b := &binding{constructor: constructor, specifiedParameters: make(map[int]interface{})}
3)设置Register
参数,包括执行Interface
、Parameters
、Default
等方法。
for _, op := range options {err := op(b)if err != nil {return err}}
4)读取构造方法返回值类型,如果Register
设置过container.Interface()
,则container.Interface()
的值(b.resolveTypes[i]
)作为构造方法的类型。
resolveType := reflectedResolver.Out(i)if len(b.resolveTypes) > i && b.resolveTypes[i] != nil { //如果指定了映射的interface,则使用指定的if !resolveType.Implements(b.resolveTypes[i]) {return errors.New("resolve type " + resolveType.String() + " not implement " + b.resolveTypes[i].String())}resolveType = b.resolveTypes[i]}
5)以构造方法返回值类型为key,以binding方法为体将该结构存储到container下。如果该key存在过,则叠加存储;如果该key不存在,则创建。
if namedBinding, has := c.bind[resolveType]; has { //增加新bindingnamedBinding.addNewBinding(b, b.isDefault)} else { //没有注册过这个接口的任何绑定c.bind[resolveType] = newNamedBinding(b)}
2.func (c *Container) Resolve(abstraction interface{}, options ...ResolveOption) error
前面Register
方法把实现的构造方法、类型、参数记录到container
的bind
字段。
Resolve
方法根据方法类型寻找匹配的bind
字段,与abstraction
指针进行绑定。
1)设置Resolve
参数,包括执行Arguments
、ResolveName
等方法。
for _, op := range options {err := op(b)if err != nil {return err}}
2)abstraction
必须是指针
if receiverType.Kind() == reflect.Ptr {
3)从bind结构中找到匹配的接口类型
elem := receiverType.Elem()b, err := c.getBinding(elem, option.name)if err != nil {return errors.New("resolve type: " + receiverType.String() + " no concrete found for: " + elem.String())}
4)根据Arguments
获取构造方法的参数,替换Register传入的Parameters
参数
args := b.specifiedParametersif len(option.args) > 0 {for i, v := range option.args {args[i] = v}}oldArgs := b.specifiedParametersb.specifiedParameters = argsdefer func() {b.specifiedParameters = oldArgs}()
5)找到构造方法、也知道参数,调用该方法绑定实现对象
instance, err := b.resolve(c)if err != nil {return err //errors.New("resolve type: " + receiverType.String() + " " + err.Error())}reflect.ValueOf(abstraction).Elem().Set(reflect.ValueOf(instance))
长安链ioc还提供其他方法调用,逻辑比较清晰,大家可自行分析。
长安链源码学习v2.2.1--ioc机制(十)相关推荐
- 长安链源码学习--提案(Proposer)(五)
作者:明神特烦恼 公众号:明神特烦恼 提案一般是共识流程中第一步,后面步骤为多阶段的投票,最终达到一致.这里分析提案将独立于共识,分析如何生成待共识的消息.提案的高度信息.提案人确认等由其他共识模块传 ...
- DotText源码学习——ASP.NET的工作机制
--本文是<项目驱动学习--DotText源码学习>系列的第一篇文章,在这之后会持续发表相关的文章. 概论 在阅读DotText源码之前,让我们首先了解一下ASP.NET的工作机制,可以使 ...
- Vue源码学习——v2.5.8
1. cache util 利用闭包,每个调用cached函数的方法都会生成一个cache变量,在cache变量中做缓存 /*** Create a cached version of a pure ...
- Kubernetes调度器源码学习(三):Preempt抢占机制、调度失败与重试处理
本文基于Kubernetes v1.22.4版本进行源码学习 5.Preempt抢占机制 当高优先级的Pod没有找到合适的节点时,调度器会尝试抢占低优先级的Pod的节点.抢占过程是将低优先级的Pod从 ...
- Opencascade源码学习之模型数据
Opencascade源码学习之模型数据 1.模型数据 2.几何工具 1.插值和拟合 1.分析一组点 2.基本插值和近似 3.2D 插值 4.3D 插值 5.2D 拟合 6.3D 拟合 7.曲面拟合 ...
- ERNIE源码学习与实践:为超越ChatGPT打下技术基础!
★★★ 本文源自AlStudio社区精品项目,[点击此处]查看更多精品内容 >>> ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由 ...
- 文心ERNIE源码学习与实践:为超越ChatGPT打下技术基础!
ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由ERNIE发展起来的文心大模型,是GPT3.0的强劲竞争对手,未来还会挑战ChatGPT的江湖地位! ...
- spring源码学习之路---深入AOP(终)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...
- Promise源码学习(2)
Promise源码学习(2) 本篇为上一篇源码学习(1)的补充,主要是来介绍Promise.all()和Promise.race()方法. 闲话少叙,进入正题 Promise.race() 首先来简单 ...
最新文章
- Zookeeper整理(一)- 写操作产生事件,写操作与Watcher对应关系
- linuxz指令大全
- ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程
- java动态生成HTML文件
- 草根程序员进入BAT
- 浅析NDI 5(一)基于NDI 5如何打造全球NDI演播室?
- android gpu平板 推荐,性能强的不像话,最强安卓平板华为平板M6上手
- 想要提高自己的写作水平?吃透这篇文章就够了
- PDF怎么转长图?这些方法不妨了解一下
- (二)ArcGIS JS 加载动态地图服务
- 远程办公一段时间了,你(团队)进入状态没?
- ubuntu 安装方法 wubi
- 不定方程非负整数解个数
- 电力电子中的有源和无源
- Mac os下时间戳转换
- terminate called after throwing an instance of ‘c10::Error‘ chunk expects at least a 1-d tensor
- 信息学奥赛一本通 1256:献给阿尔吉侬的花束 | OpenJudge NOI 2.5 7218:献给阿尔吉侬的花束
- 4.2.3 标准编码
- 在mysql中通配符_mysql查询中通配符的使用
- ubuntu如何查看网卡名称_修改Ubuntu网卡名称