# Baa 核心
## 創建應用
`func New() *Baa`
快速創建一個新的應用實例。
`func Instance(name string) *Baa`
獲取一個命名實例,如果實例不存在則調用 `New()` 創建并且命名。
命名實例 用于不同模塊間共享 baa實例的場景。在 入口中創建,在其他模塊中 `baa.Instance(name)` 可獲取指定的實例。
`func Default() *Baa`
使用默認的應用實例。
Default 是 `Instance` 的一個默認實現,是全局唯一的實例。在共享場景下,不需要傳遞 baa 直接調用 `baa.Default()` 即可訪問同一實例。
使用示例:
```
app := baa.New()
app := baa.Default()
app := baa.Instance("myApp")
myApp := baa.Instance("myApp")
```
## 路由管理
baa 基于 http resetfull 模式設計了路由管理器,具體見 [路由](https://github.com/go-baa/doc/tree/master/zh-CN/router.md) 一節。
## 中間件
baa 支持通過 中間件 機制,注入請求過程,實現類似插件的功能,具體見 [中間件](https://github.com/go-baa/doc/tree/master/zh-CN/middleware.md) 一節。
## 依賴注入
依賴注入(dependency injection)簡稱 DI,是 baa 實現的核心,baa 所有組件基于DI組裝起來的。
baa組件的更換,見 [更換內置引擎](#更換內置引擎) 一節。
DI的具體使用,見 [依賴注入](https://github.com/go-baa/doc/tree/master/zh-CN/di.md) 一節。
## 運行應用
`func (b *Baa) Run(addr string)`
指定一個監聽地址,啟動一個HTTP服務。
示例:
```
app := baa.Default()
app.Run(":1323")
```
`func (b *Baa) RunTLS(addr, certfile, keyfile string)`
指定監聽地址和TLS證書,啟動一個HTTPS服務。
示例:
```
app := baa.Default()
app.RunTLS(":8443", "cert/cert.cert", "cert/server.key")
```
## 環境變量
`BAA_ENV`
baa 通過 系統環境變量 `BAA_ENV` 來設置運行模式。
`baa.Env`
外部程序可以通過 `baa.Env` 變量來獲取 baa 當前的運行模式。
運行模式常量
```
// DEV mode
DEV = "development"
// PROD mode
PROD = "production"
// TEST mode
TEST = "test"
```
* baa.DEV 開發模式
* baa.PROD 產品模式
* baa.TEST 測試模式
示例代碼:
```
if baa.Env == baa.PROD {
// 應用運行在產品模式
}
```
## 調試
`func (b *Baa) Debug() bool`
返回是否是調試模式,應用可以根據是否運行在調試模式,來輸出調試信息。
`func (b *Baa) SetDebug(v bool)`
默認根據運行環境決定是否開啟調試模式,可以通過該方法開啟/關閉調試模式。
> 在 產品模式 下,默認關閉調試模式,其他模式下默認開啟調試模式。
`func (b *Baa) Logger() Logger`
返回日志器,在應用中可以調用日志器來輸出日志。
示例:
```
app := baa.New()
log := app.Logger()
log.Println("test")
```
## 錯誤處理
> 錯誤輸出,只是給瀏覽器返回錯誤,但并不會阻止接下來綁定的方法。
`func (b *Baa) NotFound(c *Context)`
調用該方法會直接 輸出 404錯誤。
`func (b *Baa) Error(err error, c *Context)`
調用該方法會直接輸出 500錯誤,并根據運行模式決定是否在瀏覽器中返回具體錯誤。
示例
```
app := baa.New()
app.Get("/", func(c *baa.Context) {
c.Baa().NotFound(c)
})
app.Get("/e", func(c *baa.Context) {
c.Baa().Error(errors.New("something error"), c)
})
```
## 更換內置引擎
baa 采用以DI為核心的框架設計,內置模塊均可使用新的實現通過DI更換。
### 日志器
baa 將日志抽象為 `baa.Logger` 接口,只要實現了該接口,就可以注冊為日志器。
baa 內置的日志器使用的是標準包的 `log` 實例。
更換日志器:
```
app := baa.New()
baa.SetDI("logger", newLogger)
```
> logger 是內置名稱,該命名被用于全局日志器。
### 路由器
只要實現接口 `baa.Router` 接口即可。
```
app := baa.New()
baa.SetDI("router", newRouter)
```
> router 是內置名稱,該命名被用于全局路由器。
baa 除了內置的 tree路由,還新增了兩個路由器可用,見 [router](https://github.com/go-baa/router)
### 模板引擎
只要實現接口 `baa.Renderer` 接口即可。
```
app := baa.New()
baa.SetDI("render", newRender)
```
> render 是內置名稱,該命名被用于模板渲染。
### DIer
甚至依賴注入管理器,自己也能被替換,只要實現 `baa.Dier` 接口即可。
請注意要在第一個設置,并且重設以上三個引擎,因為你的注入管理器中默認并沒有內置引擎,BAA將發生錯誤。
```
app := baa.New()
app.SetDIer(newDIer)
app.SetDI("logger", log.New(os.Stderr, "[Baa] ", log.LstdFlags))
app.SetDI("render", new(baa.Render))
app.SetDI("router", baa.NewTree(app))
```