欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語言注入容器,go 模塊引用

Go語言的應(yīng)用

Go語言由Google公司開發(fā),并于2009年開源,相比Java/Python/C等語言,Go尤其擅長并發(fā)編程,性能堪比C語言,開發(fā)效率肩比Python,被譽為“21世紀(jì)的C語言”。

創(chuàng)新互聯(lián)公司是一家以網(wǎng)絡(luò)技術(shù)公司,為中小企業(yè)提供網(wǎng)站維護、網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站備案、服務(wù)器租用、域名注冊、軟件開發(fā)、小程序制作等企業(yè)互聯(lián)網(wǎng)相關(guān)業(yè)務(wù),是一家有著豐富的互聯(lián)網(wǎng)運營推廣經(jīng)驗的科技公司,有著多年的網(wǎng)站建站經(jīng)驗,致力于幫助中小企業(yè)在互聯(lián)網(wǎng)讓打出自已的品牌和口碑,讓企業(yè)在互聯(lián)網(wǎng)上打開一個面向全國乃至全球的業(yè)務(wù)窗口:建站服務(wù)熱線:18980820575

Go語言在云計算、大數(shù)據(jù)、微服務(wù)、高并發(fā)領(lǐng)域應(yīng)用應(yīng)用非常廣泛。BAT大廠正在把Go作為新項目開發(fā)的首選語言。

Go語言應(yīng)用范圍:

1、服務(wù)端開發(fā):以前你使用C或者C++做的那些事情,用Go來做很合適,例如日志處理、文件系統(tǒng)、監(jiān)控系統(tǒng)等;

2、DevOps:運維生態(tài)中的Docker、K8s、prometheus、grafana、open-falcon等都是使用Go語言開發(fā);

3、網(wǎng)絡(luò)編程:大量優(yōu)秀的Web框架如Echo、Gin、Iris、beego等,而且Go內(nèi)置的 net/http包十分的優(yōu)秀;

4、Paas云平臺領(lǐng)域:Kubernetes和Docker Swarm等;

5、分布式存儲領(lǐng)域:etcd、Groupcache、TiDB、Cockroachdb、Influxdb等;

6、區(qū)塊鏈領(lǐng)域:區(qū)塊鏈里面有兩個明星項目以太坊和fabric都使用Go語言;

7、容器虛擬化:大名鼎鼎的Docker就是使用Go語言實現(xiàn)的;

8、爬蟲及大數(shù)據(jù):Go語言天生支持并發(fā),所以十分適合編寫分布式爬蟲及大數(shù)據(jù)處理。

go依賴注入dig包使用-來自uber公司

原文鏈接:

github:

Dependency Injection is the idea that your components (usually structs in go) should receive their dependencies when being created. This runs counter to the associated anti-pattern of components building their own dependencies during initialization. Let’s look at an example.

Suppose you have a Server struct that requires a Config struct to implement its behavior. One way to do this would be for the Server to build its own Config during initialization.

This seems convenient. Our caller doesn’t have to be aware that our Server even needs access to Config . This is all hidden from the user of our function.

However, there are some disadvantages. First of all, if we want to change the way our Config is built, we’ll have to change all the places that call the building code. Suppose, for example, our buildMyConfigSomehow function now needs an argument. Every call site would need access to that argument and would need to pass it into the building function.

Also, it gets really tricky to mock the behavior of our Config . We’ll somehow have to reach inside of our New function to monkey with the creation of Config .

Here’s the DI way to do it:

Now the creation of our Server is decoupled from the creation of the Config . We can use whatever logic we want to create the Config and then pass the resulting data to our New function.

Furthermore, if Config is an interface, this gives us an easy route to mocking. We can pass anything we want into New as long as it implements our interface. This makes testing our Server with mock implementations of Config simple.

The main downside is that it’s a pain to have to manually create the Config before we can create the Server . We’ve created a dependency graph here – we must create our Config first because of Server depends on it. In real applications these dependency graphs can become very large and this leads to complicated logic for building all of the components your application needs to do its job.

This is where DI frameworks can help. A DI framework generally provides two pieces of functionality:

A DI framework generally builds a graph based on the “providers” you tell it about and determines how to build your objects. This is very hard to understand in the abstract, so let’s walk through a moderately-sized example.

We’re going to be reviewing the code for an HTTP server that delivers a JSON response when a client makes a GET request to /people . We’ll review the code piece by piece. For simplicity sake, it all lives in the same package ( main ). Please don’t do this in real Go applications. Full code for this example can be found here .

First, let’s look at our Person struct. It has no behavior save for some JSON tags.

A Person has an Id , Name and Age . That’s it.

Next let’s look at our Config . Similar to Person , it has no dependencies. Unlike Person , we will provide a constructor.

Enabled tells us if our application should return real data. DatabasePath tells us where our database lives (we’re using sqlite). Port tells us the port on which we’ll be running our server.

Here’s the function we’ll use to open our database connection. It relies on our Config and returns a *sql.DB .

Next we’ll look at our PersonRepository . This struct will be responsible for fetching people from our database and deserializing those database results into proper Person structs.

PersonRepository requires a database connection to be built. It exposes a single function called FindAll that uses our database connection to return a list of Person structs representing the data in our database.

To provide a layer between our HTTP server and the PersonRepository , we’ll create a PersonService .

Our PersonService relies on both the Config and the PersonRepository . It exposes a function called FindAll that conditionally calls the PersonRepository if the application is enabled.

Finally, we’ve got our Server . This is responsible for running an HTTP server and delegating the appropriate requests to our PersonService .

The Server is dependent on the PersonService and the Config .

Ok, we know all the components of our system. Now how the hell do we actually initialize them and start our system?

First, let’s write our main() function the old fashioned way.

First, we create our Config . Then, using the Config , we create our database connection. From there we can create our PersonRepository which allows us to create our PersonService . Finally, we can use this to create our Server and run it.

Phew, that was complicated. Worse, as our application becomes more complicated, our main will continue to grow in complexity. Every time we add a new dependency to any of our components, we’ll have to reflect that dependency with ordering and logic in the main function to build that component.

As you might have guessed, a Dependency Injection framework can help us solve this problem. Let’s examine how.

The term “container” is often used in DI frameworks to describe the thing into which you add “providers” and out of which you ask for fully-build objects. The dig library gives us the Provide function for adding providers and the Invoke function for retrieving fully-built objects out of the container.

First, we build a new container.

Now we can add new providers. To do so, we call the Provide function on the container. It takes a single argument: a function. This function can have any number of arguments (representing the dependencies of the component to be created) and one or two return values (representing the component that the function provides and optionally an error).

The above code says “I provide a Config type to the container. In order to build it, I don’t need anything else.” Now that we’ve shown the container how to build a Config type, we can use this to build other types.

This code says “I provide a *sql.DB type to the container. In order to build it, I need a Config . I may also optionally return an error.”

In both of these cases, we’re being more verbose than necessary. Because we already have NewConfig and ConnectDatabase functions defined, we can use them directly as providers for the container.

Now, we can ask the container to give us a fully-built component for any of the types we’ve provided. We do so using the Invoke function. The Invoke function takes a single argument – a function with any number of arguments. The arguments to the function are the types we’d like the container to build for us.

The container does some really smart stuff. Here’s what happens:

That’s a lot of work the container is doing for us. In fact, it’s doing even more. The container is smart enough to build one, and only one, instance of each type provided. That means we’ll never accidentally create a second database connection if we’re using it in multiple places (say multiple repositories).

Now that we know how the dig container works, let’s use it to build a better main.

The only thing we haven’t seen before here is the error return value from Invoke . If any provider used by Invoke returns an error, our call to Invoke will halt and that error will be returned.

Even though this example is small, it should be easy to see some of the benefits of this approach over our “standard” main. These benefits become even more obvious as our application grows larger.

One of the most important benefits is the decoupling of the creation of our components from the creation of their dependencies. Say, for example, that our PersonRepository now needs access to the Config . All we have to do is change our NewPersonRepository constructor to include the Config as an argument. Nothing else in our code changes.

Other large benefits are lack of global state, lack of calls to init (dependencies are created lazily when needed and only created once, obviating the need for error-prone init setup) and ease of testing for individual components. Imagine creating your container in your tests and asking for a fully-build object to test. Or, create an object with mock implementations of all dependencies. All of these are much easier with the DI approach.

I believe Dependency Injection helps build more robust and testable applications. This is especially true as these applications grow in size. Go is well suited to building large applications and has a great DI tool in dig . I believe the Go community should embrace DI and use it in far more applications.

golang反射框架Fx

Fx是一個golang版本的依賴注入框架,它使得golang通過可重用、可組合的模塊化來構(gòu)建golang應(yīng)用程序變得非常容易,可直接在項目中添加以下內(nèi)容即可體驗Fx效果。

Fx是通過使用依賴注入的方式替換了全局通過手動方式來連接不同函數(shù)調(diào)用的復(fù)雜度,也不同于其他的依賴注入方式,F(xiàn)x能夠像普通golang函數(shù)去使用,而不需要通過使用struct標(biāo)簽或內(nèi)嵌特定類型。這樣使得Fx能夠在很多go的包中很好的使用。

接下來會提供一些Fx的簡單demo,并說明其中的一些定義。

1、一般步驟

大致的使用步驟就如下。下面會給出一些完整的demo

2、簡單demo

將io.reader與具體實現(xiàn)類關(guān)聯(lián)起來

輸出:

3、使用struct參數(shù)

前面的使用方式一旦需要進行注入的類型過多,可以通過struct參數(shù)方式來解決

輸出

如果通過Provide提供構(gòu)造函數(shù)是生成相同類型會有什么問題?換句話也就是相同類型擁有多個值呢?

下面兩種方式就是來解決這樣的問題。

4、使用struct參數(shù)+Name標(biāo)簽

在Fx未使用Name或Group標(biāo)簽時不允許存在多個相同類型的構(gòu)造函數(shù),一旦存在會觸發(fā)panic。

輸出

上面通過Name標(biāo)簽即可完成在Fx容器注入相同類型

5、使用struct參數(shù)+Group標(biāo)簽

使用group標(biāo)簽同樣也能完成上面的功能

輸出

基本上Fx簡單應(yīng)用在上面的例子也做了簡單講解

1、Annotated(位于annotated.go文件) 主要用于采用annotated的方式,提供Provide注入類型

源碼中Name和Group兩個字段與前面提到的Name標(biāo)簽和Group標(biāo)簽是一樣的,只能選其一使用

2、App(位于app.go文件) 提供注入對象具體的容器、LiftCycle、容器的啟動及停止、類型變量及實現(xiàn)類注入和兩者映射等操作

至于Provide和Populate的源碼相對比較簡單易懂在這里不在描述

具體源碼

3、Extract(位于extract.go文件)

主要用于在application啟動初始化過程通過依賴注入的方式將容器中的變量值來填充給定的struct,其中target必須是指向struct的指針,并且只能填充可導(dǎo)出的字段(golang只能通過反射修改可導(dǎo)出并且可尋址的字段),Extract將被Populate代替。 具體源碼

4、其他

諸如Populate是用來替換Extract的,而LiftCycle和inout.go涉及內(nèi)容比較多后續(xù)會單獨提供專屬文件說明。

在Fx中提供的構(gòu)造函數(shù)都是惰性調(diào)用,可以通過invocations在application啟動來完成一些必要的初始化工作:fx.Invoke(function); 通過也可以按需自定義實現(xiàn)LiftCycle的Hook對應(yīng)的OnStart和OnStop用來完成手動啟動容器和關(guān)閉,來滿足一些自己實際的業(yè)務(wù)需求。

Fx框架源碼解析

主要包括app.go、lifecycle.go、annotated.go、populate.go、inout.go、shutdown.go、extract.go(可以忽略,了解populate.go)以及輔助的internal中的fxlog、fxreflect、lifecycle

gorilla/websocket使用教程

最近打算為我的網(wǎng)站添加一個服務(wù)器資源監(jiān)視功能,需要服務(wù)端主動向前端推動資源占用數(shù)據(jù)。這時Http則不能達到要求。所以自然想到采用websocket。以前使用SpringBoot時使用websocket很簡單,只需要將ServerEndpointExporter注入到bean容器并配合相應(yīng)注解即可創(chuàng)建一個websocket服務(wù)。這里要感謝各位前輩的封裝讓我們能盡快實現(xiàn)相應(yīng)的功能,但本次出于學(xué)習(xí)目并不是公司項目(效率穩(wěn)定性至上)同時使用的開發(fā)語言為Golang,其web開發(fā)生態(tài)也不會像Java那樣豐富,最后選擇了開源實現(xiàn) gorilla/websocket 項目地址

執(zhí)行 go get github.com/gorilla/websocket 添加依賴

我們知道websocket由http升級而來,首先會發(fā)送附帶Upgrade請求頭的Http請求,所以我們需要在處理Http請求時攔截請求并判斷其是否為websocket升級請求,如果是則調(diào)用 gorilla/websocket 庫相應(yīng)函數(shù)處理升級請求。

首相要創(chuàng)建Upgrader實例,該實例用于升級請求

其中 CheckOringin 是一個函數(shù),該函數(shù)用于攔截或放行跨域請求。函數(shù)返回值為 bool 類型,即 true 放行, false 攔截。如果請求不是跨域請求可以不賦值,我這里是跨域請求并且為了方便直接返回 true

此時已經(jīng)成功升級為websocket連接并獲得一個conn實例,之后的發(fā)送接收操作皆有conn完成其類型為websocket.Conn。

首先向客戶端發(fā)送消息使用 WriteMessage(messageType int, data []byte) ,參數(shù)1為消息類型,參數(shù)2消息內(nèi)容

示例:

接受客戶端消息使用 ReadMessage() 該操作會阻塞線程所以建議運行在其他協(xié)程上。該函數(shù)有三個返回值分別是,接收消息類型、接收消息內(nèi)容、發(fā)生的錯誤當(dāng)然正常執(zhí)行時錯誤為 nil。一旦連接關(guān)閉返回值類型為-1可用來終止讀操作。

示例:

同時可以為連接設(shè)置關(guān)閉連接監(jiān)聽,函數(shù)為 SetCloseHandler(h func(code int, text string) error) 函數(shù)接收一個函數(shù)為參數(shù),參數(shù)為nil時有一個默認實現(xiàn),其源碼為:

可以看到作為參數(shù)的函數(shù)的參數(shù)為int和string類型正好和前端的close(long string)對應(yīng)即前端調(diào)用close(long string)關(guān)閉連接后兩個參數(shù)會被發(fā)送給后端并最終被 func(code int, text string) error 所使用。

示例:

則斷開連接時將打印code和text

注意:要想使斷連處理生效必須要有 ReadMessage() 操作否則不會觸發(fā)斷連處理操作。

以上是常用基礎(chǔ)操作點擊 官方API手冊 學(xué)習(xí)更多。

最后:大幻夢森羅萬象狂氣斷罪眼\ (??) /

文章標(biāo)題:go語言注入容器,go 模塊引用
分享URL:http://chinadenli.net/article7/dsgdooj.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)品牌網(wǎng)站制作做網(wǎng)站網(wǎng)站內(nèi)鏈外貿(mào)網(wǎng)站建設(shè)自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)