>  기사  >  PHP 프레임워크  >  Laravel의 종속성 주입 구현 원리는 무엇입니까?

Laravel의 종속성 주입 구현 원리는 무엇입니까?

WBOY
WBOY원래의
2022-02-18 11:06:446152검색

Laravel에서 종속성 주입의 구현 원칙은 클래스 메서드 리플렉션을 사용하여 매개변수 유형을 얻은 다음 컨테이너를 사용하여 인스턴스를 구성하고 콜백 함수를 사용하여 이를 호출하는 것입니다. 주입된 객체 생성자는 매개변수를 가질 수 없습니다. 그렇지 않으면 오류가 보고되며 종속성 주입은 Router 클래스에 의해 호출되어야 합니다. 그렇지 않으면 새 메서드를 사용하여 직접 주입을 수행할 수 없습니다.

Laravel의 종속성 주입 구현 원리는 무엇입니까?

이 기사의 운영 환경: Windows 10 시스템, Laravel 버전 6, Dell G3 컴퓨터.

Laravel의 종속성 주입 구현 원리는 무엇인가요?

laravel 컨테이너에는 제어 반전과 종속성 주입이 포함되어 있습니다. 이를 사용하려면 먼저 객체를 바인딩하고 필요할 때 직접 make를 사용하여 검색할 수 있습니다.

구체적인 분석은 http://laravelacademy.org/post/769.html

보통 저희 통화 내용은 다음과 같습니다.

$config = $container->make('config');
$connection = new Connection($this->config);

이 방법의 장점은 인스턴스를 직접 새로 만들 필요가 없다는 것입니다. 이 인스턴스를 여러 위치에서 공유할 수도 있습니다.

그런데 이것이 종속성 주입과 무슨 관련이 있나요? 실제 종속성 주입에서는 메서드에 매개 변수 값을 전달할 필요가 없으며, 메서드 매개 변수 유형만 지정하면 코드가 자동으로 관계를 찾아 자동으로 주입합니다. 의존성.

이 기능은 다음과 같이 laravel의 Controller, Job 등에 반영될 수 있습니다.

class TestController extends Controller
{
    public function anyConsole(Request $request, Auth $input)
    {
        //todo
    }
}

자동 종속성 주입을 구현하는 방법을 살펴보겠습니다.

커널은 index.PHP로 호출되며 다층을 통해 호출됩니다. 커널 파이프라인과 To 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'](형식 줄: AppHttpControllerDatacenterRealTimeController@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->resolveClassMethodDependacies 이름만 봐도 이 메소드가 우리가 찾고 있는 메소드라는 것을 알 수 있습니다. $this->parametersWithoutNulls()는 null 문자를 필터링하는 것입니다. $class 및 $method는 각각 AppHttpControllerDatacenterRealTimeController 및 anyConsole과 같습니다.

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;
}

reflection 클래스 메서드를 통해 클래스 매개변수 배열을 가져온 다음 이를 순회하여 $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

종속성 주입은 좋지만 Router 클래스에서 호출해야 합니다. 그렇지 않으면 새 메서드를 사용하여 직접 주입을 수행할 수 없습니다. 따라서 Controller 및 Job 클래스만 이 기능을 사용할 수 있습니다.

【관련 추천: laravel 동영상 튜토리얼

위 내용은 Laravel의 종속성 주입 구현 원리는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.