laravel 의존 주입 분석

9855 단어 PHP
laravel 용 기 는 반전 제어 와 의존 주입 을 포함 하고 있 습 니 다. 사용 하면 대상 bid 를 먼저 사용 하고 필요 할 때 make 를 사용 하여 가 져 오 면 됩 니 다.구체 적 인 분석 참조:http://laravelacademy.org/post/769.html
보통 우리 의 호출 은 다음 과 같다.
$config = $container->make('config');
$connection = new Connection($this->config);

이해 하기 쉽다. 이러한 장점 은 바로 new 의 실례 를 직접 사용 하지 않 아 도 된다 는 것 이다. 방법의 값 은 변 함 이 없고 여러 곳 에서 이 실례 를 공유 할 수 있다.
그러나 이것 은 주입 에 의존 하 는 것 과 어떤 관계 가 있 습 니까? 진정한 의존 주입 은 방법 에 어떠한 매개 변수 값 도 전달 하지 않 고 방법 매개 변수 유형 만 가리 키 고 코드 자동 검색 관 계 는 자동 주입 에 의존 합 니 다.
이 특성 은 laravel 의 Controller, Job 등에 서 다음 과 같이 나타 날 수 있 습 니 다.
class TestController extends Controller
{
    public function anyConsole(Request $request, Auth $input)
    {
        //todo
    }
}

우 리 는 그 가 어떻게 자동 의존 주입 을 실현 하 는 지 보 자.index.php 에서 호출 Kernel 하고 다 층 Kernel 파 이 프 를 통 해 호출 한 다음 에 Router 까지 다 층 중간 부품 파 이 프 를 통 해 호출 된다.최종 위치 지정Illuminate/Routing/Route.php 124 번 째 줄.
public function run(Request $request)
{
    $this->container = $this->container ?: new Container;
    try {
        if (! is_string($this->action['uses'])) {
            return $this->runCallable($request);
        }

        if ($this->customDispatcherIsBound()) {
            return $this->runWithCustomDispatcher($request);
        }

        return $this->runController($request);
    } catch (HttpResponseException $e) {
        return $e->getResponse();
    }
}
$this->action['uses'] (예 를 들 어 \App\Http\Controller\Datacenter\RealTimeController@anyConsole 문자열 여 부 를 판단 하고 $this->customDispatcherIsBound 사용자 정의 경로 가 연결 되 어 있 는 지 여 부 를 판단 합 니 다.그리고 뛰 어 $this->runController($request).
protected function runController(Request $request)
{
    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 은 각각 다음 과 같 습 니 다. \App\Http\Controller\Datacenter\RealTimeControlleranyConsole.
protected function resolveClassMethodDependencies(array $parameters, $instance, $method)
{
    if (! method_exists($instance, $method)) {
        return $parameters;
    }

    return $this->resolveMethodDependencies(
        $parameters, new ReflectionMethod($instance, $method)
    );
}
new ReflectionMethod($instance, $method) 유형 을 얻 는 방법의 반사 대상 으로 문 서 를 참조 합 니 다.http://www.php.net/manual/zh/class.reflectionmethod.php
다음은 Illuminate/Routing/RouteDependencyResolverTrait.php 54 번 째 줄 로 넘 어 갑 니 다.
public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
{
    $originalParameters = $parameters;

    foreach ($reflector->getParameters() as $key => $parameter) {
        $instance = $this->transformDependency(
            $parameter, $parameters, $originalParameters
        );

        if (! is_null($instance)) {
            $this->spliceIntoParameters($parameters, $key, $instance);
        }
    }

    return $parameters;
}

반사 류 방법 을 통 해 클래스 매개 변수 배열 을 얻 은 다음 에 $this->transformDependency 방법 에 전달 합 니 다.인 스 턴 스 가 가 져 오지 못 하면 호출 $this->spliceIntoParameters 에서 이 인 자 를 알 수 있 습 니 다.
protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters)
{
    $class = $parameter->getClass();
    if ($class && ! $this->alreadyInParameters($class->name, $parameters)) {
        return $this->container->make($class->name);
    }
}

마침내 용기 의 그림 자 를 보 았 다. 그래, 최종 대상 은 용기 의 make 방법 으로 꺼 냈 다.이로써 매개 변 수 는 구 조 된 후에 최종 적 으로 runController 방법의 call_user_func_array 에 의 해 회 조 될 것 이다.
요약: 1. 주입 원리 에 의존 하 는 것 은 바로 유형 방법 으로 반사 하여 매개 변수 유형 을 얻 은 다음 에 용기 구 조 를 이용 하여 인 스 턴 스 를 잘 만 드 는 것 이다.그리고 리 셋 함 수 를 사용 하여 리 셋 합 니 다.2. 주입 대상 구조 함수 에 인자 가 있 으 면 안 됩 니 다.그렇지 않 으 면 잘못 보고 할 것 이다.Missing argument 1 3. 주입 에 의존 하 는 것 이 좋 지만 Router 류 에서 조정 해 야 합 니 다. 그렇지 않 으 면 new 방식 으로 주입 할 수 없습니다.그래서 왜 Controller, Job 류 만 이 기능 을 사용 할 수 있 습 니까?

좋은 웹페이지 즐겨찾기