laravel中的服务容器

控制反转(IoC)和依赖注入(DI)

IoC 容器 —— Laravel 的核心

(1)laravel 的请求生命周期

几乎所有php框架,或者对php程序来说,都是单一入口,都是以index.php开始的。那么laravel的

入口文件都干了些什么事呢?

所有请求通过web服务器(apapache/nignx)引导至 public/index.php。

第一件事就是从bootstrap/app.php脚本中检索laravel应用程序的实例。

一 、引入app.php(创建一个新的应用)

$app = require_once __DIR__.'/../bootstrap/app.php';

app.php文件当中,第一件事就是创建一个新的实例;

$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') );

(1) 实例化Application
class Application extends Container implements ApplicationContract, HttpKernelInterface
{
 public function __construct($basePath = null)
  {
      if ($basePath) {
          $this->setBasePath($basePath);
      }

      $this->registerBaseBindings();

      $this->registerBaseServiceProviders();

      $this->registerCoreContainerAliases();
  }
}

实例化的时候干了4件事

  • 绑定当前实例路径
  • 注册基本绑定
  • 注册所有基本服务提供者
  • 注册所有核心依赖到容器中
(2)将重要的接口绑定到容器
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);
 

绑定单例到容器(http,kernel,debug)

(3)返回应用程序(当前实例)

二、启动应用程序

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

这里 Illuminate\Contracts\Http\Kernel::class只是一个接口,这里的$app->make()

这里有深入研究 Laravel 执行流程(五)之 认识 Make

简单来说就是从容器中解析给定的类型。那么这行代码可以理解为实例化位于app/Http/Kernel.php这个类。

(1)HTTP/控制器内核

所有请求都会Http的核心类(kernel)中的handle方法处理

这个handle方法长这个样子


public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();

            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);

            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));

            $response = $this->renderException($request, $e);
        }

        $this->app['events']->dispatch(
            new Events\RequestHandled($request, $response)
        );

        return $response;
    }

简单来说就是创建了一个新的HTTP内核实例,并且实例化了一些重要的组件

应用程序的请求类型将传入的请求发送到 HTTP 内核或控制台内核。而这两个内核是用来作为所

有请求都要通过的中心位置。一个处理http请求,一个处理控制台请求。我们一般用到的是HTTP

内核。

$response = $kernel->handle( $request = Illuminate\Http\Request::capture() );
实例化了kernel传入了请求类


class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
}

继承了symfony的Request然后实现了一些接口。

从请求入口后面就可以开始处理自己业务逻辑了

三、返回

$response->send();

(2)服务容器与服务提供器

服务提供器

最重要的内核引导操作之一是加载应用程序的 服务提供器。应用程序的所有服务提供器都在 config/app.php 配置文件的 providers 数组中配置。首先,所有提供器都会调用 register 方法,接着,由 boot 方法负责调用所有被注册提供器。

服务提供器负责引导所有框架的各种组件,如数据库、队列、验证和路由组件。也就是说,框架提供的每个功能都它们来引导并配置。因此也可以说,服务提供器是整个 Laravel 引导过程中最重要的方面。

简单来说就是在容器中注册需要的类

服务容器

服务容器通过构造函数或者某些情况下通过 set 方法将类依赖注入到类中。说得专业点就是用于管理类依赖和执行依赖注入的强大工具

依赖注入与控制反转

我的理解:当一个类A需要实例化另一个类B,我们不在类A里面实例化,让其他类(专门的)来实例化,这个就叫控制反转。那怎么把实例化的类B放到类A,可以通过构造函数,或者set方法注入,这个就叫依赖注入。

在php当中一般使用类型提示注入依赖,比如管理员控制器需要注入,角色和权限

class AdminController extends controller
{
    protected $user;
    protected $role;

    public function __construct(UserServices $userServices,RoleServices $roleServices)
    {
        $this->user=$userServices;
        $this->role=$roleServices;
    }
  }

这里的UserService,RoleServices为接口

在laravel中服务容器有一个强大的功能,就是将接口绑定到给定实现。如果需要用到服务容器,一般是注入接口,如果不是就接口,也就没有必要使用了。直接注入就行了,可以使用Repository模式,事实证明,服务容器很麻烦,如果不是超大型项目,根本没有必要使用。

Laravel 的核心就是一个 IoC 容器,高级的IOC容器,他会根据类的依赖需求,自动在注册、绑定的一堆实例中搜寻符合的依赖需求,并自动注入到构造函数参数中去。这种自动搜寻依赖需求的功能,是通过反射(Reflection)实现的。

发布了33 篇原创文章 · 获赞 1 · 访问量 8303

猜你喜欢

转载自blog.csdn.net/u012914309/article/details/103421654
今日推荐