Lumen开发:lumen源码解读之初始化(5)——注册(register)与启动(boot)
版权声明:本文为博主原创文章,未经博主允许不得转载。
register()是在服务容器注册服务,
bootstrap/app.php
/** * 注册外部服务 */ $app->register(Dingo\Api\Provider\LumenServiceProvider::class); $app->register(Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class); $app->register(Maatwebsite\Excel\ExcelServiceProvider::class); /** * 注册内部服务 */ $app->register(App\Providers\User\UserServiceProvider::class); $app->register(App\Providers\Validate\ValidateServiceProvider::class); $app->register(App\Providers\Cache\CacheServiceProvider::class);
/** * Register a service provider with the application.(申请登记服务提供商) * * @param \Illuminate\Support\ServiceProvider|string $provider * @return \Illuminate\Support\ServiceProvider */ public function register($provider) {
if (! $provider instanceof ServiceProvider) { $provider = new $provider($this); } if (array_key_exists($providerName = get_class($provider), $this->loadedProviders)) { return; } $this->loadedProviders[$providerName] = true; if (method_exists($provider, 'register')) { $provider->register(); } if (method_exists($provider, 'boot')) { return $this->call([$provider, 'boot']); } }
如果不是继承ServiceProvider,则直接new一个实例,传过去的$this是$app,那边类初始化时可以接收这个对象,然后操作容器;
如果该服务已注册,则直接返回;
标记为true;
如果有register函数则执行:
如果有boot函数,则调用call函数
/** * Call the given Closure / class@method and inject its dependencies.(调用给定的闭包/类@方法并注入它的依赖项。) * * @param callable|string $callback * @param array $parameters * @param string|null $defaultMethod * @return mixed */ public function call($callback, array $parameters = [], $defaultMethod = null) { return BoundMethod::call($this, $callback, $parameters, $defaultMethod); }
/** * Call the given Closure / class@method and inject its dependencies.(调用给定的闭包/类@方法并注入它的依赖项。) * * @param \Illuminate\Container\Container $container * @param callable|string $callback * @param array $parameters * @param string|null $defaultMethod * @return mixed */ public static function call($container, $callback, array $parameters = [], $defaultMethod = null) { if (static::isCallableWithAtSign($callback) || $defaultMethod) { return static::callClass($container, $callback, $parameters, $defaultMethod); } return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) { return call_user_func_array( $callback, static::getMethodDependencies($container, $callback, $parameters) ); }); }
第一个判断需要$callback是字符串,一般调不到。
/** * Determine if the given string is in Class@method syntax.(确定给定的字符串是类”方法的语法。) * * @param mixed $callback * @return bool */ protected static function isCallableWithAtSign($callback) { return is_string($callback) && strpos($callback, '@') !== false; }
接下来看callBoundMethod方法
/** * Call a method that has been bound to the container.(调用已绑定到容器的方法。) * * @param \Illuminate\Container\Container $container * @param callable $callback * @param mixed $default * @return mixed */ protected static function callBoundMethod($container, $callback, $default) { if (! is_array($callback)) { return $default instanceof Closure ? $default() : $default; } // Here we need to turn the array callable into a Class@method string we can use to // examine the container and see if there are any method bindings for this given // method. If there are, we can call this method binding callback immediately. $method = static::normalizeMethod($callback); if ($container->hasMethodBinding($method)) { return $container->callMethodBinding($method, $callback[0]); } return $default instanceof Closure ? $default() : $default; }
判断是否为数组,不是的话,判断是否闭包,直接执行传过来的闭包或类;
将数组递归化为一个类@方法字符串;
检查容器,并查看该方法是否有任何方法绑定;
如果有的话,我们可以调用这个方法立即绑定回调;(好像用来验证的$this->methodBindings一直是空。。。)
如果没有,判断是否闭包,直接执行传过来的闭包或类;
我们再来看下调用callBoundMethod时传的闭包吧
return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) { return call_user_func_array( $callback, static::getMethodDependencies($container, $callback, $parameters) ); });
先看下getMethodDependencies方法,
/** * Get all dependencies for a given method.(获取给定方法的所有依赖项。) * * @param \Illuminate\Container\Container * @param callable|string $callback * @param array $parameters * @return array */ protected static function getMethodDependencies($container, $callback, array $parameters = []) { $dependencies = []; foreach (static::getCallReflector($callback)->getParameters() as $parameter) { static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies); } return array_merge($dependencies, $parameters); }
基本都是返回空数组,暂时先不入这个坑了,应该是对给定的回调做反射处理,获取给定调用参数的依赖性。
return call_user_func_array( $callback, [] );
那么多数情况,闭包函数执行的就是上面这段,而
$callback = [$provider, 'boot'];
所以说,就是执行了对应服务的boot方法,后面遇到其他情况,会继续做完善。
Lumen技术交流群:310493206
版权声明:本文为博主原创文章,未经博主允许不得转载。