前言
嗨,我小asong又回来了。托了两周没有更新,最近比较忙,再加上本人懒,所以嘛,嗯嗯,你们懂的。不过我明天的带来的分享,相对干货,在理论我的项目中开发也是须要用到的,所以为了可能讲明确,我特意写了一个样例,仅供参考。本文会围绕样例进行开展学习,已上传github,可自行下载。好了,不说废话了,晓得你们急不可待了,咱们间接开始吧!!!
wire
依赖注入
在介绍wire之前,咱们先来理解一下什么是依赖注入。应用过Spring的同学对这个应该不会生疏。其中管制反转(IOC)最常见的形式就叫做依赖注入。将依赖的类作为行参放入依赖中的类就成为依赖注入。这么说可能你们不太懂。用一句大白话来说,一个实例化的对象,原本我承受各种参数来结构一个对象,当初只承受一个参数,对对象的依赖是注入进来的,和它的结构形式解耦了。结构他这个管制操作也交给了第三方,即管制反转。举个例子:go中是没有类的概念的,以构造体的模式体现。假如咱们当初船类,有个浆类,咱们当初想要设置该船有12个浆,那咱们能够写出如下代码:
package mainimport ( "fmt")type ship struct { pulp *pulp}func NewShip(pulp *pulp) *ship{ return &ship{ pulp: pulp, }}type pulp struct { count int}func Newpulp(count int) *pulp{ return &pulp{ count: count, }}func main(){ p:= Newpulp(12) s := NewShip(p) fmt.Println(s.pulp.count)}
置信你们一眼就看出问题了,每当需要变动时,咱们都要从新创立一个对象来指定船桨,这样的代码不易保护,咱们变通一下。
package mainimport ( "fmt")type ship struct { pulp *pulp}func NewShip(pulp *pulp) *ship{ return &ship{ pulp: pulp, }}type pulp struct { count int}func Newpulp() *pulp{ return &pulp{ }}func (c *pulp)set(count int) { c.count = count}func (c *pulp)get() int { return c.count}func main(){ p:= Newpulp() s := NewShip(p) s.pulp.set(12) fmt.Println(s.pulp.get())}
s.pulp.set(20)
wire的应用
wireProviderInjectorProviderInitializeCronInjectorwirewire
拉了这么长,就是为了引出wire,下面的代码尽管是实现了依赖注入,这是在代码量少,构造不简单的状况下,咱们本人来实现依赖是没有问题的,当构造之间的关系变得非常复杂的时候,这时候手动创立依赖,而后将他们组装起来就会变的异样繁琐,并且很容出错。所以wire的作用就来了。在应用之前咱们先来装置一下wire。
$ go get github.com/google/wire/cmd/wire
$GOPATH/binwire$GOPATH/bin$PATH
先依据下面的简略例子,咱们先来看看wire怎么用。咱们先创立一个wire文件,文件内容如下:
//+build wireinjectpackage mainimport ( "github.com/google/wire")type Ship struct { Pulp *Pulp}func NewShip(pulp *Pulp) *Ship { return &Ship{ pulp: pulp, }}type Pulp struct { Count int}func NewPulp() *Pulp { return &Pulp{ }}func (c *Pulp)set(count int) { c.count = count}func (c *Pulp)get() int { return c.count}func InitShip() *Ship { wire.Build( NewPulp, NewShip, ) return &Ship{}}func main(){}
InitShipwirewire.Build()shipwire
$ wirewire: asong.cloud/Golang_Dream/wire_cron_example/ship: wrote /Users/asong/go/src/asong.cloud/Golang_Dream/wire_cron_example/ship/wire_gen.go
咱们看到生成了wire_gen.go这个文件:
// Code generated by Wire. DO NOT EDIT.//go:generate wire//+build !wireinjectpackage main// Injectors from mian.go:func InitShip() *Ship { pulp := NewPulp() ship := NewShip(pulp) return ship}// mian.go:type Ship struct { pulp *Pulp}func NewShip(pulp *Pulp) *Ship { return &Ship{ pulp: pulp, }}type Pulp struct { count int}func NewPulp() *Pulp { return &Pulp{}}func (c *Pulp) set(count int) { c.count = count}func (c *Pulp) get() int { return c.count}func main() {}
InitShip()
func InitShip() *Ship//+build wireinject
daoservicecontrollermodeldaoservicecontrollercontrollerserviceservicedaocroncontrollercontrollercron
//+build wireinjectpackage wireimport ( "github.com/google/wire" "asong.cloud/Golang_Dream/wire_cron_example/config" "asong.cloud/Golang_Dream/wire_cron_example/cron" "asong.cloud/Golang_Dream/wire_cron_example/cron/task" "asong.cloud/Golang_Dream/wire_cron_example/dao" "asong.cloud/Golang_Dream/wire_cron_example/service")func InitializeCron(mysql *config.Mysql) *cron.Cron{ wire.Build( dao.NewClientDB, dao.NewUserDB, service.NewUserService, task.NewScanner, cron.NewCron, ) return &cron.Cron{}}
dao.NewClientDB*sql.DBmysqldao.NewUserDB*UserDB*sql.DBservice.NewUserServiceUserService*UserDBtask.NewScanner*Scanner*UserServicecron。NewCron*Cron*Scanner
cron
cron
根底学习
咱们在日常开发或运维中,常常遇到一些周期性执行的工作或需要,例如:每一段时间执行一个脚本,每个月执行一个操作。linux给咱们提供了一个便捷的形式—— crontab定时工作;crontab就是一个自定义定时器,咱们能够利用 crontab 命令在固定的间隔时间执行指定的零碎指令或 shell script 脚本。而这个工夫距离的写法与咱们平时用到的cron 表达式类似。作用都是通过利用字符或命令去设置定时周期性地执行一些操作.
cron linuxQuartz Schedulersecondsseconds
67
[秒] [分] [时] [日] [月] [周] [年]
[年]的局部通常是能够省略的,实际上由前六局部组成。
对于各局部的定义,咱们以一个表格的模式出现:
域
是否必填
值以及范畴
通配符
秒
是
0-59
, – * /
分
是
0-59
, – * /
时
是
0-23
, – * /
日
是
1-31
, – * ? / L W
月
是
1-12 或 JAN-DEC
, – * /
周
是
1-7 或 SUN-SAT
, – * ? / L #
年
否
1970-2099
, – * /
看这个值的范畴,还是很好了解的,最难了解的是通配符,咱们着重来讲一下通配符。
,5,10,15-6-12,6,7,8,9,10,11,12**?0 0 0 8 * ?/5/10LW#
学习了通配符,上面咱们来看几个例子:
0 0 10 * * *0 */10 * * *0 0 3 1 * ?0 30 23 L * ?0 0 3 ? * L0 30,50 * * * ?
go中应用cron
githubcronrobfig/cron
cron
$ go get -u github.com/robfig/cron/v3
seconds
package mainimport ( "fmt" "time" "github.com/robfig/cron/v3")func main() { c := cron.New() c.AddFunc("@every 1s", func() { fmt.Println("task start in 1 seconds") }) c.Start() select{}}
cron.NewcronAddFunc()AddFunc()@every 1s@every@every 1h@every 1m2stime.ParseDuration()c.Start()
c.Start()select{}
cron
@yearly@annually0 0 1 1 *@monthly0 0 1 * *@weekly0 0 * * 0@daily@midnight0 0 * * *@hourly0 * * * *
cron
@every <duration>
durationtime.ParseDuration()ParseDuration
我的项目应用
cronjob
type Job interface{ Run()}
咱们须要实现这个接口,这里我就以我写的例子来做演示吧,我当初这个定时工作是周期扫DB表中的数据,实现工作如下:
package taskimport ( "fmt" "asong.cloud/Golang_Dream/wire_cron_example/service")type Scanner struct { lastID uint64 user *service.UserService}const ( ScannerSize = 10)func NewScanner(user *service.UserService) *Scanner{ return &Scanner{ user: user, }}func (s *Scanner)Run() { err := s.scannerDB() if err != nil{ fmt.Errorf(err.Error()) }}func (s *Scanner)scannerDB() error{ s.reset() flag := false for { users,err:=s.user.MGet(s.lastID,ScannerSize) if err != nil{ return err } if len(users) < ScannerSize{ flag = true } s.lastID = users[len(users) - 1].ID for k,v := range users{ fmt.Println(k,v) } if flag{ return nil } }}func (s *Scanner)reset() { s.lastID = 0}
RuncronScanner
package cronimport ( "github.com/robfig/cron/v3" "asong.cloud/Golang_Dream/wire_cron_example/cron/task")type Cron struct { Scanner *task.Scanner Schedule *cron.Cron}func NewCron(scanner *task.Scanner) *Cron { return &Cron{ Scanner: scanner, Schedule: cron.New(), }}func (s *Cron)Start() error{ _,err := s.Schedule.AddJob("*/1 * * * *",s.Scanner) if err != nil{ return err } s.Schedule.Start() return nil}
AddFunc()AddJob()cronfunc()FuncJob
// cron.gotype FuncJob func()
FuncJobJob
// cron.gofunc (f FuncJob) Run() { f()}
AddFunc()FuncJobAddJob()
func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) { return c.AddJob(spec, FuncJob(cmd))}
v3seconds
cron.New(cron.WithSeconds())
创建对象的传入这个参数就能够了。
好啦。我想要解说的完事了,代码就不运行了,已上传github,可自行下载学习:https://github.com/asong2020/…
总结
明天的文章就到这里了,这一篇总结的并不全,只是达到入门的一个成果,想要持续深刻,还须要各位小伙伴自行看文档学习呦。学会看官网文档,能力提高更多的呦。就比方工夫标准这里,如果不看文档,我就不会晓得当初应用的工夫标准是什么的,所以还是要养成看文档的好习惯。打个预报,下一期是go-elastic的教程,有须要的小伙伴能够关注一下。
结尾给大家发一个小福利吧,最近我在看[微服务架构设计模式]这一本书,讲的很好,本人也收集了一本PDF,有须要的小伙能够到自行下载。获取形式:关注公众号:[Golang梦工厂],后盾回复:[微服务],即可获取。
我翻译了一份GIN中文文档,会定期进行保护,有须要的小伙伴后盾回复[gin]即可下载。
我是asong,一名普普通通的程序猿,让我一起缓缓变强吧。欢送各位的关注,咱们下期见~~~
举荐往期文章:
- 据说你还不会jwt和swagger-饭我都不吃了带着实际我的项目我就来了
- 把握这些Go语言个性,你的程度将进步N个品位(二)
- go实现多人聊天室,在这里你想聊什么都能够的啦!!!
- grpc实际-学会grpc就是这么简略
- go规范库rpc实际
- 2020最新Gin框架中文文档 asong又捡起来了英语,用心翻译
- 基于gin的几种热加载形式
- boss: 这小子还不会应用validator库进行数据校验,开了~~~