## Mix Bean
DI、IoC 容器,參考 spring bean 設計
DI, IoC container, reference spring bean
> 該庫還有 php 版本:https://github.com/mix-php/bean
## Overview
一個創建對象以及處理對象依賴關系的庫,該庫可以實現統一管理依賴,全局對象管理,動態配置刷新等。
## Installation
- 安裝
```
go get -u github.com/mix-go/bean
```
## Usage
- `ConstructorArgs` 構造器注入
```golang
var definitions = []bean.Definition{
{
Name: "foo",
Reflect: bean.NewReflect(NewHttpClient),
ConstructorArgs: bean.ConstructorArgs{
time.Duration(time.Second * 3),
},
},
}
// 必須返回指針類型
func NewHttpClient(timeout time.Duration) *http.Client {
return &http.Client{
Timeout: timeout,
}
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*http.Client) // 返回的都是指針類型
fmt.Println(fmt.Sprintf("%+v", foo))
```
- `Fields` 字段注入
```golang
var definitions = []bean.Definition{
{
Name: "foo",
Reflect: bean.NewReflect(http.Client{}),
Fields: bean.Fields{
"Timeout": time.Duration(time.Second * 3),
},
},
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*http.Client) // 返回的都是指針類型
fmt.Println(fmt.Sprintf("%+v", foo))
```
- `ConstructorArgs + Fields` 混合使用
```golang
var definitions = []bean.Definition{
{
Name: "foo",
Reflect: bean.NewReflect(NewHttpClient),
ConstructorArgs: bean.ConstructorArgs{
time.Duration(time.Second * 3),
},
Fields: bean.Fields{
"Timeout": time.Duration(time.Second * 2),
},
},
}
// 必須返回指針類型
func NewHttpClient(timeout time.Duration) *http.Client {
return &http.Client{
Timeout: timeout,
}
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*http.Client) // 返回的都是指針類型
fmt.Println(fmt.Sprintf("%+v", foo))
```
- `NewReference` 引用
引用其他依賴注入
```golang
type Foo struct {
Client *http.Client // 引用注入的都是指針類型
}
var definitions = []bean.Definition{
{
Name: "foo",
Reflect: bean.NewReflect(Foo{}),
},
Fields: bean.Fields{
"Client": NewReference("bar"),
},
},
{
Name: "bar",
Reflect: bean.NewReflect(http.Client{}),
Fields: bean.Fields{
"Timeout": time.Duration(time.Second * 3),
},
},
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*Foo) // 返回的都是指針類型
cli := foo.Client
fmt.Println(fmt.Sprintf("%+v", cli))
```
- `Scope: SINGLETON` 單例
定義組件為全局單例
```golang
var definitions = []bean.Definition{
{
Name: "foo",
Scope: bean.SINGLETON, // 這里定義了單例模式
Reflect: bean.NewReflect(http.Client{}),
Fields: bean.Fields{
"Timeout": time.Duration(time.Second * 3),
},
},
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*http.Client) // 返回的都是指針類型
fmt.Println(fmt.Sprintf("%+v", foo))
```
- `InitMethod` 初始化方法
對象創建完成并且 `ConstructorArgs + Fields` 兩種注入全部完成后執行該方法,用來初始化處理。
```golang
type Foo struct {
Bar string
}
func (c *Foo) Init() {
c.Bar = "bar ..."
fmt.Println("init")
}
var definitions = []bean.Definition{
{
Name: "foo",
InitMethod: "Init", // 這里定義了初始化方法
Reflect: bean.NewReflect(Foo{}),
Fields: bean.Fields{
"Bar": "bar",
},
},
}
context := bean.NewApplicationContext(definitions)
foo := context.Get("foo").(*Foo) // 返回的都是指針類型
fmt.Println(fmt.Sprintf("%+v", foo))
```
- `Refresh` 動態刷新配置
這個通常用于通過微服務配置中心實現動態刷新微服務配置的功能。
```golang
type Foo struct {
Bar string
}
var definitions = []bean.Definition{
{
Name: "foo",
Reflect: bean.NewReflect(Foo{}),
Fields: bean.Fields{
"Bar": "bar",
},
},
}
context := bean.NewApplicationContext(definitions)
// 第一次獲取
foo := context.Get("foo").(*Foo)
fmt.Println(fmt.Sprintf("%+v", foo))
// 修改配置
bd := context.GetBeanDefinition("foo")
bd.Fields["Bar"] = "bar2"
bd.Refresh()
// 第二次獲取就是新的配置
foo := context.Get("foo").(*Foo)
fmt.Println(fmt.Sprintf("%+v", foo))
```
## License
Apache License Version 2.0, http://www.apache.org/licenses/