当前位置: 首页 > news >正文

Gone框架介绍27 - 再讲 Goner 和 依赖注入

gone是可以高效开发Web服务的Golang依赖注入框架
github地址:https://github.com/gone-io/gone
文档地址:https://goner.fun/zh/

文章目录

  • Goner 和 依赖注入
    • Goner的定义
    • 依赖标记
    • Goners 注册
    • Priest函数

Goner 和 依赖注入

Gone 作为一个依赖注入框架,首先需要回答的问题:什么是依赖,如何定义依赖?

在golang中已经定义了package,我们在项目中引入的package就是一种依赖;这些依赖可以利用golang项目中的.mod文件进行比较好的管理,然而这种依赖也并不是我们讨论的需要注入的依赖。

“依赖注入”,作为一个动补短语,要明确它的含义,需要问:什么依赖了什么,谁注入了谁?

在golang中,能够承载业务逻辑的结构,只有 funcstructfunc 的执行结果 依赖 函数的参数,而 struct 功能的实现 依赖 结构体的属性。无论是函数的参数 还是 结构体的属性,都是业务逻辑实现的 依赖;这样我们就回答了“什么是依赖?”:

定义

依赖,是为了实现某业务逻辑,函数或者结构体需要依赖的 外部值 或者 外部参数。

这些外部值或者外部参数,可能是代表了业务逻辑依赖的外部业务;实现我们的业务所需的业务逻辑,需要依赖这些外部业务来完成。由此可见,是 业务 依赖了 业务,那么注入的也是业务,是 业务 注入了 业务

为了对业务进行抽象,我们定义了Goner,它是一个接口,所有业务结构体都要实现它;那么,在Gone框架中,就是 Goners依赖Goners,Goners注入到Goners

Goner的定义

我们查看Goner的定义,如下:

type Goner interface {goneFlag()
}

可以看到,Goner是一个接口,要求实现一个私有方法goneFlag(),这个方法是为了标识该结构体是Goner。由于golang语法限制,在包外部是无法实现一个包内的私有方法的,为了在外部的业务代码可以实现 Goner接口 ,我们又定义了gone.Flag结构体,并且在实现了goneFlag()方法时将方法的接收者设置了为 Flag指针,如下:

type Flag struct{}func (g *Flag) goneFlag() {}

这样,业务结构体XBusiness 有且仅有 匿名嵌入gone.Flag才能完成对Goner接口的实现。gone框架要求只有Goner才可以被注册到Gone框架中,用于依赖注入的装配。
例如:

package exampleimport "github.com/gone-io/gone"type XBusiness struct {gone.Flag
}

这样设计的好处是:

  1. 限定依赖注入装配的对象都是Goner,可以简化了依赖注入装配流程实现。
  2. 限定Goner一定是指针,依赖注入时可以避免结构体的值拷贝;一方面是提高性能,另一方面是避免值拷贝时的“浅拷贝”业务对象带来的未知问题。

依赖标记

业务结构体中,并不是所有的属性都需要依赖注入,需要有一种机制标记哪些属性需要使用依赖注入。为此,我们设计了标签gone来标记需要注入的属性,如下:

type Employee interface {Work()
}type Company struct {gone.FlagBoss Employee `gone:"*"` // 标记需要依赖注入的属性
}

公司需要注入一个员工作为Boss,星号(*)表示该属性的注入只需要匹配类型,即实现 Employee 接口的Goner就可以;这种注入方式,我们称为匿名注入

需要注意

Goner 结构体需要注入的属性,可以是任意 接口 或者 结构体指针,这里并不限定是Goner,只有Goner注册到Gone框架时限定Goner类型。

公司的老板不可能是任何员工都能担任的,与匿名注入对应的就是具名注入,注入标签可以将星号替换为需要注入Goner的Id 字符串,如下:

type Company struct {gone.FlagBoss Employee `gone:"boss"` // 具名注入,要求该属性注入一个Id=boss的Goner
}

Goners 注册

为了完成依赖注入的自动装配,我们需要将所有的Goners注册到Gone框架中。下面给出上面公司依赖员工这个例子的完整代码,如下:

package mainimport ("fmt""github.com/gone-io/gone"
)type Employee interface {Work()Name() string
}type Company struct {gone.FlagBoss Employee `gone:"boss"` // 标记需要依赖注入的属性
}func (c *Company) Start() {fmt.Printf("Company start, boss is %s\n", c.Boss.Name())c.Boss.Work()
}type EmployeeImpl struct {gone.Flagname string
}func (e *EmployeeImpl) Work() {fmt.Printf("I am working, my name is %s\n", e.Name())
}func (e *EmployeeImpl) Name() string {return e.name
}func main() {gone.Prepare(func(cemetery gone.Cemetery) error {//注册EmployeeImplcemetery.Bury(&EmployeeImpl{name: "Scott"}, gone.GonerId("boss"))//注册Companycemetery.Bury(&Company{})return nil}).Run(func(company *Company) {company.Start()})
}

可以看到,我们使用了cemetery.Bury 方法完成了Goner到Gone框架的注册;该方法第二参数可以指定被注册的Goner的Id,如果没有指定Id,Gone框架会自动为Goner随机生成一个Id。在具名注入时,我们会用到注册时的GonerId来作为gone标签的值。

Priest函数

在上面代码中,gone.Prepare 方法接收的参数为一个匿名函数,它的形式如下:

func(cemetery Cemetery) error

在Gone框架中,这样形式的函数被定义为Priest函数,专门负责Goners的注册。

Priest的定义

type Priest func(cemetery Cemetery) error

大多数情况下,我们可以不用手动编写Priest代码;在gone中提供了 gone辅助工具,可以为我们自动生成Priest函数代码:自动生成Priest

相关文章:

Gone框架介绍27 - 再讲 Goner 和 依赖注入

gone是可以高效开发Web服务的Golang依赖注入框架 github地址:https://github.com/gone-io/gone 文档地址:https://goner.fun/zh/ 文章目录 Goner 和 依赖注入Goner的定义依赖标记Goners 注册Priest函数 Goner 和 依赖注入 Gone 作为一个依赖注入框架&am…...

【Python/Pytorch 】-- 滑动窗口算法

文章目录 文章目录 00 写在前面01 基于Python版本的滑动窗口代码02 算法效果 00 写在前面 写这个算法原因是:训练了一个时序网络,该网络模型的时序维度为32,而测试数据的时序维度为90。因此需要采用滑动窗口的方法,生成一系列32…...

Clickhouse集群create drop database可删除集群数据库或只删除本地数据库

集群环境下,在任意一个节点创建数据库,如果加上了ON CLUSTER clustername,则在集群环境的所有节点上都创建了该数据库,并在集群环境的所有节点上都创建了该数据库对应的目录,且数据库的metadata_path对应的目录路径在所…...

【docker】adoptopenjdk/openjdk8-openj9:alpine-slim了解

adoptopenjdk/openjdk8-openj9:alpine-slim 是一个 Docker 镜像的标签,它指的是一个特定的软件包,用于在容器化环境中运行 Java 应用程序。 镜像相关的网站和资源: AdoptOpenJDK 官方网站 - AdoptOpenJDK 这是 AdoptOpenJDK 项目的官方网站&…...

Vscode interaction window

python 代码关联到 jupyter 模式 在代码前添加: # %%print("hellow wolrd!") 参考文档链接: https://code.visualstudio.com/docs/python/jupyter-support-py...

后端数据null前端统一显示成空

handleNullValues方法在封装请求接口返回数据时统一处理 // null 转 function handleNullValues(data) {// 使用递归处理多层嵌套的对象或数组function processItem(item) {if (Array.isArray(item)) {return item.map(processItem);} else if (typeof item object &&…...

【设计模式深度剖析】【9】【行为型】【访问者模式】| 以博物馆的导览员为例加深理解

👈️上一篇:备忘录模式 | 下一篇:状态模式👉️ 设计模式-专栏👈️ 文章目录 访问者模式定义英文原话直译如何理解呢? 访问者模式的角色类图代码示例 访问者模式的应用优点缺点使用场景 示例解析:博物馆的导览员代码示例 访问…...

Salesforce‘s 爱因斯坦机器人助手引领工业聊天机器人时代

CRM的对话式人工智能助手,根据公司数据提供可靠的人工智能响应及日本工业聊天机器人现状 【前言】 爱因斯坦助手(Einstein Copilot)提供可靠的响应,因为它基于公司独特的数据和元数据,使其能够深入了解公司的业务和客…...

Day7—zookeeper基本操作

ZooKeeper介绍 ZooKeeper(动物园管理员)是一个分布式的、开源的分布式应用程序的协调服务框架,简称zk。ZooKeeper是Apache Hadoop 项目下的一个子项目,是一个树形目录服务。 ZooKeeper的主要功能 配置管理 分布式锁 集群管理…...

计算机组成原理---Cache的基本工作原理习题

对应知识点: Cache的基本原理 1.某存储系统中,主存容量是Cache容量的4096倍,Cache 被分为 64 个块,当主存地址和Cache地址采用直接映射方式时,地址映射表的大小应为()(假设不考虑一致维护和替…...

springboot项目中切数据库(mysql-> pg)带来的适配问题:typeHandler

一、数据表中有一张表,名为role_permission,DDL如下: CREATE TABLE "public"."role_permission" ( "role_id" varchar(64) COLLATE "pg_catalog"."default" NOT NULL, "permiss…...

从零开始的<vue2项目脚手架>搭建:vite+vue2+eslint

前言 为了写 demo 或者研究某些问题,我经常需要新建空项目。每次搭建项目都要从头配置,很麻烦。所以我决定自己搭建一个项目初始化的脚手架(取名为 lily-cli)。 脚手架(scaffolding):创建项目时…...

Hadoop升级失败,File system image contains an old layout version -64

原始版本 Hadoop 3.1.3 升级版本 Hadoop 3.3.3 报错内容如下 datasophon 部署Hadoop版本 查看Hadoop格式化版本 which hadoop-daemon.sh/bigdata/app/hadoop-3.1.3/sbin/hadoop-daemon.sh删除原来的旧版本 rm -rf /bigdata/app/hadoop-3.1.3查看环境变量 env|grep HADOOPHAD…...

[机器学习算法]决策树

1. 理解决策树的基本概念 决策树是一种监督学习算法,可以用于分类和回归任务。决策树通过一系列规则将数据划分为不同的类别或值。树的每个节点表示一个特征,节点之间的分支表示特征的可能取值,叶节点表示分类或回归结果。 2. 决策树的构建…...

springboot应用cpu飙升的原因排除

1、通过top或者jps命令查到是那个java进程, top可以看全局那个进程耗cpu,而jps则默认是java最耗cpu的,比如找到进程是196 1.1 top (推荐)或者jps命令均可 2、根据第一步获取的进程号,查询进程里那个线程最占用cpu,发…...

反激开关电源EMI电路选型及计算

EMI :开关电源对电网或者其他电子产品的干扰 EMI :传导与辐射 共模电感的滤波电路,La和Lb就是共模电感线圈。这两个线圈绕在同一铁芯上,匝数和相位都相 同(绕制反向)。 这样,当电路中的正常电流(差模&…...

vue3前端对接后端的图片验证码

vue3前端对接后端的图片验证码 <template> <image :src"captchaUrl" alt"图片验证码" click"refreshCaptcha"></image> </template><script setup>import {ref} from "vue";import {useCounterStore} …...

【Unity】RPG2D龙城纷争(四)要诀、要诀数据集

更新日期&#xff1a;2024年6月20日。 项目源码&#xff1a;第五章发布&#xff08;正式开始游戏逻辑的章节&#xff09; 索引 简介要诀数据集&#xff08;AbilityDataSet&#xff09;一、定义要诀数据集类二、要诀属性1.要诀类型2.攻击距离3.基础命中、暴击率4.基础属性加成5.…...

一种基于非线性滤波过程的旋转机械故障诊断方法(MATLAB)

在众多的旋转机械故障诊断方法中&#xff0c;包络分析&#xff0c;又称为共振解调技术&#xff0c;是目前应用最为成功的方法之一。首先&#xff0c;对激励引起的共振频带进行带通滤波&#xff0c;然后对滤波信号进行包络谱分析&#xff0c;通过识别包络谱中的故障相关的特征频…...

HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现(五)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...