[TOC] >[danger] # 执行对象注册 >[success] ## 执行对象注册 控制器注册的设计模式相对来说比较简单,也易于管理,但是由于每一次请求都是新建一个控制器对象来处理,并且使用了反射机制,会有一定的性能损耗。 执行对象注册相对来说是一种比较高效的执行方式,但是运行机制、设计模式与控制器注册完全不同。与字面意思相同,执行对象注册是在注册时便给定一个实例化的对象,以后每一个请求都交给该对象(同一对象)处理,该对象常驻内存不释放。由于相比较控制器注册来说,执行对象注册方式在处理请求的时候不需要不停地创建/销毁控制器对象,因此请求处理效率会高很多。 这种注册方式的缺点也很明显,服务端进程在启动时便需要初始化这些执行对象,并且这些对象需要自行负责对自身数据的并发安全维护。执行对象的定义没有严格要求,也没有强行要求继承```gmvc.Controller```控制器基类,因为在请求进入时没有自动初始化流程,内部的成员变量需要自行维护(包括变量初始化,变量销毁等)。 执行对象的路由规则和控制器注册相同,同时也支持动态路由规则注册(当然也支持```{method}```变量)。 我们可以通过```ghttp.BindObject```方法完成执行对象的注册。 gitee.com/johng/gf/blob/master/geg/frame/mvc/controller/demo/object.go ```go package demo import "gitee.com/johng/gf/g/net/ghttp" type Object struct {} func init() { ghttp.GetServer().BindObject("/object", &Object{}) } func (o *Object) Show(r *ghttp.Request) { r.Response.Write("It's show time bibi!") } ``` 可以看到,执行对象在进行服务注册时便生成了一个对象(执行对象在Web Server启动时便生成),此后不管多少请求进入,Web Server都是将请求转交给该对象对应的方法进行处理。需要注意的是,公开方法的定义与控制器注册不同,必须为以下形式: func(r *ghttp.Request) 否则无法完成注册,调用注册方法时会有错误提示,形如: panic: interface conversion: interface {} is xxx, not func(*ghttp.Request) 该示例执行后可以通过,通过```http://127.0.0.1:8199/object/show```查看效果。 >[success] ## 对象方法注册 对象方法注册原理类似于控制器方法注册,只公开执行对象中的特定方法。 来看一个例子: ```go package demo import ( "gitee.com/johng/gf/g/net/ghttp" ) type ObjectMethod struct {} func init() { obj := &ObjectMethod{} ghttp.GetServer().BindObjectMethod("/object-method", obj, "Show1, Show2, Show3") ghttp.GetServer().Domain("localhost").BindObjectMethod("/object-method", obj, "Show4") } func (o *ObjectMethod) Show1(r *ghttp.Request) { r.Response.Write("show 1") } func (o *ObjectMethod) Show2(r *ghttp.Request) { r.Response.Write("show 2") } func (o *ObjectMethod) Show3(r *ghttp.Request) { r.Response.Write("show 3") } func (o *ObjectMethod) Show4(r *ghttp.Request) { r.Response.Write("show 4") } ``` 这个例子比较简单,并且也演示了域名绑定执行对象方法的操作。ObjectMethod对象的 ```http://127.0.0.1:8199/object-method/show1``` ```http://127.0.0.1:8199/object-method/show2``` ```http://127.0.0.1:8199/object-method/show3``` 这3个接口只能通过127.0.0.1的IP访问,而Show4这个方法只能通过 ```http://localhost:8199/object-method/show4``` 访问。 >[success] ## RESTful对象注册 和REST控制器注册类似,只不过注册的是一个实例化的对象。我们可以通过```ghttp.BindObjectRest```方法完成REST对象的注册。 gitee.com/johng/gf/blob/master/geg/frame/mvc/controller/demo/object_rest.go ```go package demo import "gitee.com/johng/gf/g/net/ghttp" // 测试绑定对象 type ObjectRest struct {} func init() { ghttp.GetServer().BindObjectRest("/object-rest", &ObjectRest{}) } // RESTFul - GET func (o *ObjectRest) Get(r *ghttp.Request) { r.Response.Write("RESTFul HTTP Method GET") } // RESTFul - POST func (c *ObjectRest) Post(r *ghttp.Request) { r.Response.Write("RESTFul HTTP Method POST") } // RESTFul - DELETE func (c *ObjectRest) Delete(r *ghttp.Request) { r.Response.Write("RESTFul HTTP Method DELETE") } // 该方法无法映射,将会无法访问到 func (c *ObjectRest) Hello(r *ghttp.Request) { r.Response.Write("Hello") } ```