Laravel 容器自动加载依赖的方法 (3864 views)

不耳

2017-01-17 17:29:46

laravel的App::make()是如何解决实例化时所需的依赖的? 比如说:A类的构造函数参数依赖B类 class A {public function __construct(B $b) {}} 实例化A类,需要new A(new B); 而laravel的容器可以这样:App:make(A::class),自动的解决了B类的依赖,它是如何做到的?

首先看容器的核心类:Illuminate\Container\Container的make方法,里面调用了bulid方法,这个bulid是解决依赖的核心:

第一步:创建PHP的反射类ReflectionClass的对象,可以解析一个类的信息

$reflector = new ReflectionClass($concrete); 

第二步:调用它的getConstructor方法,可以获取类的构造函数,它返回一个php的ReflectionMethod类的对象

$constructor = $reflector->getConstructor();

第三步:调用ReflectionMethod类的getParameters方法,获取构造函数的参数。它返回一个数组,成员是php的ReflectionParameter类的对象

$dependencies = $constructor->getParameters();

第四步:根据参数,实现所有的依赖。

$instances = $this->getDependencies($dependencies, $parameters);

$this->getDependencies()方法具体的看源码,有点复杂,分3个类别处理 1.容器有第二个参数时,如果吻合类型,直接用第二个参数解决依赖。 2.如果容器绑定过这个类,用call_user_func()调用自定义的闭包。 3.如果不符合以上,则嵌套调用App::make()来实例化依赖。

第五步:调用ReflectionClass对象的newInstanceArgs方法,创建一个新的类的实例,并返回最终的解决了依赖的对象。

return $reflector->newInstanceArgs($instances)
Tags: Laravel 依赖