laravel容器包含控制反转和依赖注入,只要先绑定对象,根据需要可以直接在make中获取即可。
通常,我们的调用如下。
$ config=$ container-make (‘config‘);
$ connection=new connection ($ this-config );
很容易理解呢。 这样做的好处是,您可以不直接新建实例。 方法的值不变。 此外,可以在多个位置共享实例。
但是,这和依赖注入有什么关系? 真正的依赖注入不需要将参数值传递给方法,只要指定方法参数类型,代码自动搜索关系就依赖于自动注入。
该特性见于laravel的控制器、Job等中,如下所示。
classtestcontrollerextendscontroller
{
publicfunctionanyconsole (请求$请求,自动输入) )。
{
//待办事宜
}
}
看看他是如何实现自动依赖注入的:
从index.php调用Kernel,通过多层Kernel管道调用,到达Router,然后通过多层中间件管道调用。 最终
illuminate/routing/route.PHP第124行。
publicfunction run (请求$请求)。
{
$ this-container=$ this-container?新容器;
try {
if (! is _ string ($ this-action (‘uses‘) } ) ) )。
返回$ this-run callable ($ request );
}
if ($ this-customdispatcherisbound ) ) }
返回$ this -运行withcustomdispatcher ($ request;
}
返回$ this -运行控制器($ request );
}catch(httpresponseexception$e ) {
返回$ e-getresponse (;
}
}
确定$ this-action [‘uses’] (格式行(app(http )控制器数据中心) [电子邮件保护] )是否为字符串,然后单击$ this-custed
保护性功能控制器(请求$请求) )。
{
list($class、$method )=explode、$this-action、) uses ) );
$ parameters=$ this-resolveclassmethoddependencies (
$this-parametersWithoutNulls ()、$class和$method
);
if (! method _ exists ($ instance=$ this-container-make ) $class )、$method ) }{
throw new NotFoundHttpException;
}
return call _ user _ func _ array ([ $ instance,$method],$parameters );
}
$ this-resolveclassmethoddependencies这种方法只要看一下名字就知道是我们要找的方法。 $this-parametersWithoutNulls ) )是过滤后的空白字符,$class、$method分别是 apphttpcontrollerdata centerrred
protectedfunctionresolveclassmethoddependencies (阵列$参数,$实例,$方法) ) ) )。
{
if (! method_exists($instance,$method ) )
返回$ parameters;
}
返回$ this-resolvemethoddependencies (
$parameters,newreflectionmethod($instance,$method )。
);
}
new ReflectionMethod($instance,$method是获取类方法的反射对象。 请参阅文档。
跳到illuminate/routing/routedependencyresolvertrait.PHP中的第54行。
publicfunctionresolvemethoddependencies (array $ parameters,reflectionfunctionabstract $ reflector ) )。
{
$ original parameters=$ parameters;
foreach ($ reflector-get parameters ) ) as $key=$parameter ) {
$ instance=$ this-transform dependency (
$parameter、$parameters、$originalParameters
);
if (! is_null($instance ) }{
$ this-spliceintoparameters ($ parameters、$key、$instance );
}
}
返回$ parameters;
}
类参数数组是通过反射类方法获得的,并传递给$this-transformDependency方法。 如果无法获取实例,请调用$this-spliceIntoParameters以明确参数。
protectedfunctiontransformdependency (reflection parameter $ parameter、$parameters、$originalParameters ) )。
{
$class=$parameter-getClass (;
if ($class! $ this-alreadyinparameters ($ class-name,$parameters ) )
返回$ this-container-make ($ class-name );
}
}
终于看到了容器的影子。 没错,最终对象是用容器的make方法取出的。 现在将生成参数,并最终由runController方法的call_user_func_array进行回调。
总结:
1 .依赖注入原理,实际上是用类方法反射,获取参数类型,用容器做一个很好的例子。 然后使用回调函数调用。
2 .注入目标构造函数不能有参数。 否则我就报告错误。 缺少协议1
3 .依赖注入是好的,但它必须从Router类中引发。 否则,用直接new方式无法实现注入。 所以,只有控制器、Job类才能使用这个特性。
php laravel依赖注入浅析
标签: