## 依赖注入 (Bean)
参考了 Java Spring 的依赖注入 (DI) 与控制反转 (IoC),具体实现就是通过 Bean 的方式,Mix 的实现非常简单高效,并且可独立使用,基于 [PSR-11](https://www.php-fig.org/psr/psr-11/) 标准实现。
## 组件
使用 [composer]([https://www.phpcomposer.com/](https://www.phpcomposer.com/)) 安装:
~~~
composer require mix/bean
~~~
## 依赖配置
负责描述依赖注入的结构关系,在 mix 里对应 manifest.php 文件的 `beans` 或者 `beanPath` 字段 (框架会遍历目录读取全部依赖配置),依赖配置是一个数组,其中每一个节点为一个 `bean` ,每个 `bean` 包含以下属性:
- name:依赖名称,默认等于 class 的值,通常只有在一个类需多次注入不同属性时使用,需给相同的类定义不同的名称。
- scope:作用域,值可为:BeanDefinition::PROTOTYPE 每次获取新的实例、BeanDefinition::SINGLETON 获取单例
- class:类的路径,通常使用 ::class 的方式获取
- properties:属性注入,配置为需注入的属性,内部的 key 将注入成类的属性名称,value 将赋值为属性的值。
- constructorArgs:构造参数注入,配置为需注入的参数,参数将依顺序传递给类的构造函数。
- ref:引用的另一个 `bean` 的 `name`
以下是一个日志类的依赖配置范例:
- 最终被调用的是 Logger 类,所以该类定义了 name,方便重写类功能时无需修改业务代码,只需修改依赖配置即可 ,其他类因为在当前程序中只有使用一次,所以都没有定义单独的 name ,因为默认 name 等于 class。
- 为了提升性能 Logger 类被定义为 BeanDefinition::SINGLETON 单例模式。
- 根据 Logger 类的源码可知,该类构造函数并没有强制要求传入参数,所以采用属性注入 (properties),而 MultiHandler 类源码只能通过构造函数实例化所以采用构造函数注入 (constructorArgs)。
- 范例一共定义了四个类,依赖关系都是通过 ref 来关联的,其中 Logger 类的 handler 属性注入了 MultiHandler 类的实例,而 MultiHandler 类实例初始化时注入了一个对象数组,对象数组为 StdoutHandler / FileHandler 两个类,而 FileHandler 类在实例化时又注入了一些配置参数。
~~~
// 依赖配置
'beans' => [
// 日志
[
// 名称
'name' => 'log',
// 作用域
'scope' => \Mix\Bean\BeanDefinition::SINGLETON,
// 类路径
'class' => \Mix\Log\Logger::class,
// 属性注入
'properties' => [
// 日志记录级别
'levels' => ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'],
// 处理器
'handler' => ['ref' => \Mix\Log\MultiHandler::class],
],
],
// 日志处理器
[
// 类路径
'class' => \Mix\Log\MultiHandler::class,
// 构造函数注入
'constructorArgs' => [
// 标准输出处理器
['ref' => \Mix\Log\StdoutHandler::class],
// 文件处理器
['ref' => \Mix\Log\FileHandler::class],
],
],
// 日志标准输出处理器
[
// 类路径
'class' => \Mix\Log\StdoutHandler::class,
],
// 日志文件处理器
[
// 类路径
'class' => \Mix\Log\FileHandler::class,
// 属性注入
'properties' => [
// 日志目录
'dir' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'runtime' . DIRECTORY_SEPARATOR . 'logs',
// 日志轮转类型
'rotate' => \Mix\Log\FileHandler::ROTATE_DAY,
// 最大文件尺寸
'maxFileSize' => 0,
],
],
],
~~~
## 通过依赖注入实例化
由于 mix 的命令行 App 启动时,已经在内部通过依赖配置信息初始化了一个 context 的属性,该属性为 Mix\Bean\ApplicationContext 的实例,负责 Bean 的调度:
```
// 获取context
$context = app()->context;
// 简化调用
$context = context();
```
因此以下方法即可在 mix 中通过依赖注入实例化一个类:
- 通过依赖名称获取类实例
```
$object = context()->get($beanName);
```
- 通过依赖名称获取类实例并传入参数
```
$params = [
'request' => $request,
'response' => $response,
];
$object = context()->getBean($beanName, $params);
```
- 欢迎使用 MixPHP
- 安装说明
- 全栈开发
- 微服务开发
- Phar 开发
- 如何部署
- 独立部署
- Nginx
- Supervisord
- 新手教程
- 命令行常识
- 进程管理
- 热更新
- 全局变量
- 调试程序
- 入门须知
- 命名空间
- 自动加载
- 入口文件
- 增改应用
- 自动补全 IDE
- 核心功能
- 配置 (manifest.php)
- 依赖注入
- 事件调度
- 验证器
- 验证器定义
- 验证规则
- 静态调用
- 日志 Monolog
- 缓存
- 协程
- 什么是协程
- 开启协程
- Runtime
- 简介
- 创建协程 xgo + Channel
- 创建协程 xgo + WaitGroup
- xgo
- xdefer
- Channel
- WaitGroup
- Timer + Ticker
- Signal
- Select
- Context
- WorkerPool
- 数据库
- Database
- Database
- Connection
- QueryBuilder
- ExecutedEvent
- Redis
- Redis
- Connection
- CalledEvent
- 命令行
- 简介
- Application
- 创建命令
- 命令参数
- 打印与颜色
- 守护进程
- 后台运行
- Web/API 应用
- 简介
- 编写一个接口
- 服务器
- 路由 FastRoute
- 中间件
- 请求
- 响应
- 文件上传
- 控制器
- 视图
- Auth
- Session
- Guzzle
- HTTP 404/500
- 安全建议
- WebSocket 应用
- 简介
- 服务器
- 客户端
- Client
- JavaScript
- Swoole
- nginx代理
- 60s无消息断线
- Micro 微服务
- 简介
- 编写一个微服务
- Mix Micro
- Go Micro
- gRPC
- JSON-RPC
- 服务注册
- 配置中心
- 熔断与降级
- 调用链追踪
- 服务限流
- Sync Invoke 同步调用
- 简介
- 服务器
- 客户端
- TCP 应用
- 简介
- 服务器
- 客户端
- Telnet
- PHP
- Swoole
- UDP 应用
- 简介
- 服务器
- 客户端
- NC
- Swoole
- 第三方接入
- EasyWeChat
- Sentry
- Doctrine Cache
- 常见问题
- 如何利用 CPU 多核
- 连接多个数据库
- 如何设置跨域
- form-data 上传文件失败
- 输出大于 2M 的文件失败