目录
目录
一.什么是 DI依赖注入/IOC控制反转. #
DI依赖注入
参考 浅谈IOC--说清楚IOC是什么
二.什么是IOC容器. #
三.什么是服务提供者(ServiceProvider)
四.什么是门面(Facade). #
五.Application和Kernel #
啥都不说,直接上代码
user = $user;
}
}
$user = new UserController(new UserModel());
?>
User控制器依赖UserModel,实例化的时候,直接注入。
IOC控制反转 #
先说IOC和DI的区别吧!
IOC是一种设计思想
DI是一种设计模式
所以两者有本质上的区别。DI是IOC的一种实现方法(还有ServiceLocator等其他设计模式)。 所谓的反转,主要指由 主动依赖 到 被动依赖 。
//主动依赖
function __construct() {
$this->user = new UserModel();
}
//被动依赖
function __construct(UserModel $user) {
$this->user = $user;
}
IOC容器 是Laravel的核心设计模式,对于laravel的应用和理解是非常有必要深入学习的!
IOC思想实现了高度解耦,那么,问题来了,如何管理这些分散的模块呢?这就是容器的任务了!
可以想象成,在IOC容器中,装着(注册)很多模块。当用户需要一个模块的时候,可以从中拿出来。当提取的模块依赖另一个模块的时候,容器会自动注入,再返回给用户(反射机制实现)。
是不是碉堡了?大批互相依赖的模块被完美解耦并统一管理了!
假设模块一多,那么容器不是越来越大?每次加载,岂不是加载好久? 能不能弄一条管子,连接着模块,插在容器上,需要再通过管道获取呢?这样子,容器只是装着管头而已,就不怕被撑大了!
这条管子就是 服务提供者。
服务提供者本身也是一个类,不过这个类只有启动和注册两个函数。
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//绑定到容器
$this->app->singleton(
'Riak\Contracts\Connection',
function ($app) {
return new Connection($app['config']['riak']);
}
);
}
服务提供者在config/app.php中配置,laravel自动注册到容器中。
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
...
/*
* Application Service Providers...
*/
app\Providers\AppServiceProvider::class,
app\Providers\AuthServiceProvider::class,
...
]
程序猿总是偷懒的,每次要模块,都要去容器里面拿,多麻烦啊!找个人代拿行不?这送货小哥就叫Facade门面。文档中叫静态代理。
送货小哥都是在config/app.php 中注册的。
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Route' => Illuminate\Support\Facades\Route::class,
...
],
查看Illuminate\Support\Facades\Route代码,可以发现只有getAccessFacade()方法,这就是交代送啥货的函数,继承了Facade这个小哥基类。
class Route extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'router';
}
}
注册了Facade门面后,就可以在任意地方使用了!
文档有详细的使用方式 Laravel 架构 — Facades。
Laravel中的门面(Facade)是一种提供简洁的静态接口的类,它封装了一个服务容器中注册的类的实例,让你可以通过静态方法调用其方法。门面提供了一种简洁的语法来访问Laravel框架的各种功能,使得代码编写更加方便和可读性更高。
在Laravel中,你可以使用`Facade`类来创建自定义的门面,或者直接使用Laravel提供的内置门面。一些常用的Laravel内置门面包括:
1. `Route`:用于定义应用程序的路由。
2. `DB`:用于执行数据库查询和操作。
3. `Auth`:提供身份验证和授权功能。
4. `Cache`:用于缓存数据。
5. `Session`:用于处理会话数据。
6. `View`:用于渲染视图。
7. `File`:用于文件操作。
使用门面时,你可以直接调用门面类的静态方法,而不需要手动创建相关对象或解析依赖。Laravel的门面充分利用了PHP的魔术方法和依赖注入容器来实现这一便利的功能。
例如,使用`Route`门面注册一个GET路由的示例:
```php
use Illuminate\Support\Facades\Route;
Route::get('/hello', function () {
return 'Hello, Laravel!';
});
```
在上述示例中,我们使用了`Route`门面的`get`静态方法来定义一个GET路由,它会将请求的URL与处理函数进行绑定,并在匹配时返回"Hello, Laravel!"。
总体来说,门面是Laravel框架中一种非常便利的工具,它简化了对框架功能的访问和调用,使得代码的可读性和可维护性更好。
不难发现,在引导程序开始初始化的时候,也就是在boostrap\app.php文件,里面一来就new了一个 Illuminate\Foundation\Application。下面分别注册了 Http\Kernel、Console\Kernel、Exceptions\Handler等。
这里可以这么理解,new一个Application,可以看作是创造了一个空间,这个空间初始化的时候,就会为自己注入一个容器,也就是在空间中放了一个容器。
在 Illuminate\Foundation\Application.php 中的 registerBaseBindings() 函数可以查看到容器注入源码。
至于kernel,可以看成是这个空间的工人,有各种各样的工人,每个工人都有自己的工作。好比HttpKernel,负责处理http请求以及控制整个请求流程。