前言
"external nofollow" href="https://laraweb.net/">https://laraweb.net/ 这是一个日本的网站,我觉得挺适合新手的,内容用浏览器翻译过来就ok了,毕竟日文直翻过来很好理解的
关于服务容器
"htmlcode">
$this->app->bind('sender','MailSender'); //$this->app成为服务容器。
"htmlcode">
$sender = $this->app->make('sender'); //从服务容器($this->app)创建一个sender类。
在这种情况下,将返回MailSender的实例。
"color: #ff0000">laravel容器基本认识
"htmlcode">
$app = new Illuminate\Foundation\Application( dirname(__DIR__) );
"color: #ff0000">如何在代码中获取到容器实例
第一种是
$app = app(); //app这个辅助函数定义在\vendor\laravel\framework\src\Illuminate\Foundation\helper.php
里面,,这个文件定义了很多help函数,并且会通过composer自动加载到项目中。
所以,在参与http请求处理的任何代码位置都能够访问其中的函数,比如app()。
第二种是
Route::get('/', function () { dd(App::basePath()); return ''; }); //这个其实是用到Facade,中文直译貌似叫门面,在config/app.php中,
有一节数组aliases专门用来配置一些类型的别名,第一个就是'App' => Illuminate\Support\Facades\App::class,
具体的Google一下laravel有关门面的具体实现方式
第三种是
"htmlcode">
abstract class ServiceProvider { protected $app;
"color: #ff0000">如何理解服务绑定与解析
"htmlcode">
app()->bind('service', 'this is service1'); app()->bind('service2', [ 'hi' => function(){ //say hi } ]); class Service { } app()->bind('service3', function(){ return new Service(); });
"htmlcode">
public function singleton($abstract, $concrete = null) { $this->bind($abstract, $concrete, true); }
"htmlcode">
if (! $concrete instanceof Closure) { $concrete = $this->getClosure($abstract, $concrete); }
看看bind的底层代码
public function bind($abstract, $concrete = null, $shared = false)
"htmlcode">
app()['service'] = function(){ return new Service(); };
绑定大概就这些,接下来看解析,也就是取出来用
$service= app()->make('service');
"htmlcode">
/** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @return mixed */ public function make($abstract, array $parameters = []) { return $this->resolve($abstract, $parameters); } /** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @return mixed */ protected function resolve($abstract, $parameters = []) { $abstract = $this->getAlias($abstract); $needsContextualBuild = ! empty($parameters) || ! is_null( $this->getContextualConcrete($abstract) ); // If an instance of the type is currently being managed as a singleton we'll // just return an existing instance instead of instantiating new instances // so the developer can keep using the same objects instance every time. if (isset($this->instances[$abstract]) && ! $needsContextualBuild) { return $this->instances[$abstract]; } $this->with[] = $parameters; $concrete = $this->getConcrete($abstract); // We're ready to instantiate an instance of the concrete type registered for // the binding. This will instantiate the types, as well as resolve any of // its "nested" dependencies recursively until all have gotten resolved. if ($this->isBuildable($concrete, $abstract)) { $object = $this->build($concrete); } else { $object = $this->make($concrete); } // If we defined any extenders for this type, we'll need to spin through them // and apply them to the object being built. This allows for the extension // of services, such as changing configuration or decorating the object. foreach ($this->getExtenders($abstract) as $extender) { $object = $extender($object, $this); } // If the requested type is registered as a singleton we'll want to cache off // the instances in "memory" so we can return it later without creating an // entirely new instance of an object on each subsequent request for it. if ($this->isShared($abstract) && ! $needsContextualBuild) { $this->instances[$abstract] = $object; } $this->fireResolvingCallbacks($abstract, $object); // Before returning, we will also set the resolved flag to "true" and pop off // the parameter overrides for this build. After those two things are done // we will be ready to return back the fully constructed class instance. $this->resolved[$abstract] = true; array_pop($this->with); return $object; }
第一步:
$needsContextualBuild = ! empty($parameters) || ! is_null( $this->getContextualConcrete($abstract) );
"htmlcode">
if (isset($this->instances[$abstract]) && ! $needsContextualBuild) { return $this->instances[$abstract]; }
"htmlcode">
$concrete = $this->getConcrete($abstract); ... /** * Get the concrete type for a given abstract. * * @param string $abstract * @return mixed $concrete */ protected function getConcrete($abstract) { if (! is_null($concrete = $this->getContextualConcrete($abstract))) { return $concrete; } // If we don't have a registered resolver or concrete for the type, we'll just // assume each type is a concrete name and will attempt to resolve it as is // since the container should be able to resolve concretes automatically. if (isset($this->bindings[$abstract])) { return $this->bindings[$abstract]['concrete']; } return $abstract; }
"htmlcode">
// We're ready to instantiate an instance of the concrete type registered for // the binding. This will instantiate the types, as well as resolve any of // its "nested" dependencies recursively until all have gotten resolved. if ($this->isBuildable($concrete, $abstract)) { $object = $this->build($concrete); } else { $object = $this->make($concrete); } ... /** * Determine if the given concrete is buildable. * * @param mixed $concrete * @param string $abstract * @return bool */ protected function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof Closure; }
"htmlcode">
$this->build($concrete) /** * Instantiate a concrete instance of the given type. * * @param string $concrete * @return mixed * * @throws \Illuminate\Contracts\Container\BindingResolutionException */ public function build($concrete) { // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be // used as resolvers for more fine-tuned resolution of these objects. // 如果传入的是闭包,则直接执行闭包函数,返回结果 if ($concrete instanceof Closure) { return $concrete($this, $this->getLastParameterOverride()); } // 利用反射机制,解析该类。 $reflector = new ReflectionClass($concrete); // If the type is not instantiable, the developer is attempting to resolve // an abstract type such as an Interface of Abstract Class and there is // no binding registered for the abstractions so we need to bail out. if (! $reflector->isInstantiable()) { return $this->notInstantiable($concrete); } $this->buildStack[] = $concrete; // 获取构造函数 $constructor = $reflector->getConstructor(); // If there are no constructors, that means there are no dependencies then // we can just resolve the instances of the objects right away, without // resolving any other types or dependencies out of these containers. // 如果没有构造函数,则表明没有传入参数,也就意味着不需要做对应的上下文依赖解析。 if (is_null($constructor)) { // 将 build 过程的内容 pop,然后直接构造对象输出。 array_pop($this->buildStack); return new $concrete; } // 获取构造函数的参数 $dependencies = $constructor->getParameters(); // Once we have all the constructor's parameters we can create each of the // dependency instances and then use the reflection instances to make a // new instance of this class, injecting the created dependencies in. // 解析出所有上下文依赖对象,带入函数,构造对象输出 $instances = $this->resolveDependencies( $dependencies ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances); }
总结
以上所述是小编给大家介绍的Laravel服务容器的绑定与解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
桃源资源网 Design By www.nqtax.com
暂无“详解Laravel服务容器的绑定与解析”评论...