### 简介:
服务定位器是框架流行一种设计模式,它和依赖注入一样都是控制反转(IOC)的实现,目的在于解耦组件和应用之间的依赖;举个简单例子,我们有个日志组件,系统所有应用程序都
会用到这个日志组件,每次使用我们需要通过new实例化对象,这样的问题是导致整个系统都是new Logger()实例化代码,万一某天组件的名称改了,那所有实例化都要跟着改变;
### 思路:
相对于依赖注入,服务定位器的实现其实很简单,用一个容器注册组件,应用程序用过key获取组件实例
### 简单的代码:
```php
// 这是一个服务定位器
class ServiceLocator {
public function get() {}
public function set() {}
}
// 注册组件
$locator = new ServiceLocator();
$locator->set('logger', new Logger());
// 使用组件
$logger = $locator->get('loggger');
$logger->write();
```
### zcswoole服务定位器使用
> 借鉴于Yii的设计模式,zcswoole实例化App类之后,将App实例赋值给了ZCSwoole::$app,在整个系统中可以通过ZCSwoole::$app来访问定位服务器
服务器
- 首先会读取配置文件中用户自定义组件配置信息
```php
return [
'components' => [
'logger' => [
'class' => 'zcswoole\Logger',
],
]
]
```
- 合并系统组件,用户可以覆盖系统组件配置,只要class指向自己自定义的类即可
```php
/**
* 核心组件
* @return array
*/
public function coreComponents():array
{
return [
'logger' => [
'class' => 'zcswoole\components\Logger'
],
'session' => [
'class' => 'zcswoole\components\Session'
]
];
}
```
- 注册组件
```php
/**
* 注册组件到容器
*/
public function injectComponents():void
{
foreach ($this->allComponents() as $name => $properties) {
$class = $properties['class'];
ZCSwoole::$con->set($name, ['class' => $class], $properties);
}
}
```
- 组件是在swoole_server启动start之前注册到容器的,这意味着这些组件常驻在内存中,所以涉及到状态类的或数据库连接的要注意了,这是全局周期的,状态类改变结果会
作用到另一个调用者,不要在start之前实例化数据库,这是因为在多进程不能共享一个数据库连接,否则数据会错乱