laravel源码分析之--Application 实例化

这个要启用后面很长一段时间来解析一下laravel源码,固然这也是一个浩大工程。可能至少要好几个月。固然这也是一个很好的学习机会php

前提

我是基于laravel5.4.30+php7.1+maclaravel

laravel 单入口文件

如今全部的框架都基于单入口,那么laravel框架的但入口文件在哪呢,固然public/index.php,那么简单来看一下这个文件bootstrap

//composer 这个也是一个大块头,暂时只要知道他能够自动加载类库就能够了,后面单独在分析
require __DIR__.'/../bootstrap/autoload.php';

//这个地方就是实例化Application 的过程
$app = require_once __DIR__.'/../bootstrap/app.php';

... 
//后面代码省略

那么咱们看一下bootstrap/app.php这个文件,代码:数组

//为laravel建立了一个实例容积,之后的laravel 的全部主见都会放在这个实例容器里
$app = new Illuminate\Foundation\Application(
    realpath(__DIR__.'/../')
);

Illuminate\Foundation\Application继承Illuminate\Container\Container,这个有什么用呢,后面看,简单看一下Application:php7

//构造函数
  public function __construct($basePath = null)
    {
        //注册一堆框架的目录,最后都会变成$this->instances 里面的东西,如图一
        if ($basePath) {
            $this->setBasePath($basePath);
        }
         //把application 本身绑定到本身的变量$instances中
        $this->registerBaseBindings();
        
        //注册框架一些基层服务

        $this->registerBaseServiceProviders();
        //注册核心类的别名

        $this->registerCoreContainerAliases();
    }
    
     //注册app
      protected function registerBaseBindings()
    {
        //上面说了Application 继承了Container这个使用了static::,静态延迟绑定,说面这个方法在Container 里,这个方法其实就是把Application 实例赋值到 static::$instance 
        static::setInstance($this);

       //注册一个实例到容器中,这个就变成了 $this->instances['app']=application实例
        $this->instance('app', $this);
       //这个其实和上面也是一下的,$this->instances['"Illuminate\Container\Container"]=Application 实例
        $this->instance(Container::class, $this);
    }
    
       /**
       * 绑定实例到容器中的instances 中
       */
        public function instance($abstract, $instance)
    {

        $this->removeAbstractAlias($abstract);

        $isBound = $this->bound($abstract);

        unset($this->aliases[$abstract]);

        $this->instances[$abstract] = $instance;

        if ($isBound) {
            $this->rebound($abstract);
        }
    }

clipboard.png
【图一】
其实在__construct有四个步骤:app

  • 注册全局路径composer

  • 注册自身框架

  • 注册基层服务ide

  • 注册别名
    其实注册基层服务重点函数

基层服务

咱们看一下 $this->registerBaseServiceProviders()这个步骤干了什么:

/**
    * 绑定全部的基础服务
   */
  protected function registerBaseServiceProviders()
    {
        //注册事件服务
        $this->register(new EventServiceProvider($this));
         //日志服务
        $this->register(new LogServiceProvider($this));
         //路由服务,这个里面注册了不少东西,从图二能够看出来,路由之后单独分析
        $this->register(new RoutingServiceProvider($this));
        //最后他们的实例都在 $this->bindings 里面, 如图二
    }
    
   
    public function register($provider, $options = [], $force = false)
    {

        ....
         //能够看到这个地方随带启动上面几个 服务的 `register` 方法
        if (method_exists($provider, 'register')) {
            $provider->register();
        }
           //把注册的服务放到$this->serviceProviders 并在$this->loadedProviders 中标记,保证下一次不会重新注册
          $this->markAsRegistered($provider);
      ....
    }
    
     protected function markAsRegistered($provider)
    {
        $this->serviceProviders[] = $provider;

        $this->loadedProviders[get_class($provider)] = true;
    }

clipboard.png

接下来就是$this->registerCoreContainerAliases(),看下代码:

public function registerCoreContainerAliases()
    {
      //仔细看一下,这些数据就会一个有规律,数组都是接口和这个接口实例,这也就是laravel 里的contracts
        foreach ([
            'app'                  => [\Illuminate\Foundation\Application::class, \Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class],
           //..... 省略
           
        ] as $key => $aliases) {
            foreach ($aliases as $alias) {
                $this->alias($key, $alias);
            }
        }
    }
      //能够看到这些类的
     public function alias($abstract, $alias)
    {
        $this->aliases[$alias] = $abstract;  //如图三

        $this->abstractAliases[$abstract][] = $alias;  //如图四
    }

clipboard.png
【图三】
clipboard.png
【图四】

以后返回了一个Application 实例,这一步算是完成了,也就是说bootstrap/app.php 的第一行代码就是本文的内容了,固然熟悉laravel 的朋友可能看出来,我把serverProvider中的boot给漏掉了,那是由于那里设计到php的反射,那也是能够单独拿出来的一个版块,后面再说

clipboard.png

相关文章
相关标签/搜索