五:DI 管理的对象的生命周期
一:思考题
DI仅管理长生命周期的对象的依赖注入容器,从容器里取出来的对象都是进程全局的单例对象,且协程下,一个进程会同一时间周期内处理多个请求
下图的使用方式会带来什么问题尼?

Controller也是由DI管理的对象,Controller也理所当然是一个单例,单例里面的成员属性有可能在同一时间周期内被不同的请求重写掉,
在这个例子中,有可能只有index方法利用了id这个成员属性;假设我们现在有另外的一些方法比如indexUp同样用到了id这个成员属性,那么请求
index方法和indexUp方法都会受到这个id值得变化,而导致返回结果的不一样;所以我们不该在所有有DI容器管理的对象内部的成员属性上去设置跟
请求或携程相关的状态数据;而这些状态数据应该根据协程上下文来进行处理;
二:思考题
如何实现$this->request 这样的调用方式?而不会导致协程间数据混淆?
文档上明确写了不允许这样存储状态值,为什么Hyperf的Request和Response可以?


访问get 方法结果返回为1

访问update方法 输入参数值为5 返回值为5

再访问get 方法结果返回也为5了

以上直接展示了单例中对不同请求的影响;那么要解决这种状态值的传递应该怎么处理尼?
我们移除掉对应的成员属性;

访问get 方法结果返回为null

访问update方法 输入参数值为5 返回值为5

再访问get 方法结果返回还是null

如果我们还是希望通过第一种方式获取属性值,该如何处理尼?

如果我们在一个单例对象里面注入另外一个对象的时候,是不是也会收到影响;


先访问get方法,返回结果为1

访问update方法 输入参数值为6 返回值为6

再访问get方法,返回结果也为6了

说明Inject进来的注入的对象依旧是一个单例对象,无论类里的属性是不是静态属性,都会在进程全局里共享;
所以我们务必要将所有的状态值都储存到协程上下文中去;协程上下文会在协程结束的时候自动释放掉;
所以无需担忧内存泄漏的问题;

浙公网安备 33010602011771号