Laravel 서비스 용기 의 바 인 딩 과 분석
솔직히 말 해서 첫 번 째 맏형 이 저 에 게 laravel 프레임 워 크 매 뉴 얼 을 보 여 준 그날 아침 에 저 는 절망 적 이 었 습 니 다.정말 접촉 한 적 이 없 었 기 때문에 저 같은 찌꺼기 에 게 laravel 의 입문 문턱 이 좀 높 아 졌 지만 억지로 봐 야 했 습 니 다.
그 다음 에 회사 프로젝트 의 코드 에 따라 laravel 에 대해 서도 점점 익숙 해 졌 지만 일부 표면적 인 기능 에 머 물 렀 다.예 를 들 어 주입,ORM 작업 에 의존 하고 사용자 가 이런 제 프로젝트 의 업무 논리 와 관련 된 조작 을 인증 한 다음 에 일부 구조 적 기반,예 를 들 어 서비스 제공 기,서비스 용기,미들웨어,Redis 등 처음부터 설정 해 야 할 것들 입 니 다.나 는 실제로 조작 한 적 이 없어 서 수첩 을 보 니 좀 멍 하 다.
그래서 시간 이 있 을 때 포럼 을 둘 러 보고 구 글 을 검색 해 보면 laravel 핵심 구조 에 대한 소개 와 어떻게 사용 하 는 지 에 대한 사이트(확실히 보고 수첩 을 보면 이해 하기 쉽다)를 많이 발견 할 수 있 습 니 다.다음은 제 가 괜 찮 은 사이트 의 교육 에 따라 laravel 핵심 구조의 학습 을 기록 하 겠 습 니 다.
사이트 주소:https://laraweb.net/이것 은 일본 의 사이트 입 니 다.저 는 초보 자 에 게 매우 적합 하 다 고 생각 합 니 다.내용 은 브 라 우 저 로 번역 하면 됩 니 다.왜냐하면 일본 어 를 계속 번역 하면 이해 하기 쉽 기 때 문 입 니 다.
서비스 용기
매 뉴 얼 에 이렇게 소개 되 어 있 습 니 다.Laravel 서비스 용 기 는 관리 류 의 의존 과 실행 의존 주입 에 사용 되 는 도구 입 니 다.이 꽃 명 사 를 주입 하 는 것 에 의존 하 는 것 은 실질 적 으로 클래스 의 의존 항 이 구조 함 수 를 통 해 또는 어떤 경우 에'setter'방법 을 통 해 클래스 에 주입 하 는 것 을 말한다.정말 무슨 뜻 인지 모르겠다)
『8195』서비스 용 기 는 관리 류(서비스)의 실례 화 된 메커니즘 이다.서비스 용 기 를 어떻게 사용 하 는 지 직접 보 세 요.
1.서비스 용기 에 클래스 등록(bid)
$this->app->bind('sender','MailSender');
//$this->app 。
서비스 용기 에서 클래스 생 성(make)
$sender = $this->app->make('sender');
// ($this->app) sender 。
이 경우 MailSender 의 인 스 턴 스 를 되 돌려 줍 니 다.이것 은 서비스 용기 의 가장 간단 한 사용 입 니 다.다음은 서비스 용기 에 대한 상세 한 소개 입 니 다.
laravel 용기 기본 인식
처음에 index.php 파일 에 Composer 를 불 러 와 정 의 된 자동 로 더 를 만 든 다음 bootstrap/app.php 스 크 립 트 에서 Laravel 프로그램의 인 스 턴 스 를 검색 합 니 다.Laravel 자체 가 취 하 는 첫 번 째 동작 은 application/service container 를 만 드 는 인 스 턴 스 입 니 다.
$app = new Illuminate\Foundation\Application(
dirname(__DIR__)
);
이 파일 은 laravel 프레임 워 크 에 요청 할 때마다 실 행 됩 니 다.만 든$app 은 laravel 프레임 워 크 의 응용 프로그램 인 스 턴 스 입 니 다.전체 요청 수명 주기 에 유일한 것 입 니 다.laravel 은 인증,데이터베이스,캐 시,메시지 큐 등 많은 서 비 스 를 제공 합 니 다.$app 은 용기 관리 도구 로 서 거의 모든 서비스 구성 요소 의 정례 화 와 인 스 턴 스 의 수명 주기 관 리 를 책임 집 니 다.서비스 클래스 가 필요 할 때 이 유형의 인 스 턴 스 를 용기 로 분석 하면 됩 니 다.최종 사용 방식 을 보면 laravel 용기 가 서비스 인 스 턴 스 에 대한 관 리 는 주로 다음 과 같은 몇 가지 측면 을 포함한다.코드 에서 용기 인 스 턴 스 를 가 져 오 는 방법
첫 번 째 는...
$app = app();
//app \vendor\laravel\framework\src\Illuminate\Foundation\helper.php
이 파일 은 많은 help 함 수 를 정의 하고 coposer 를 통 해 프로젝트 에 자동 으로 불 러 옵 니 다.따라서 http 요청 처리 에 참여 하 는 모든 코드 위치 에서 그 함수 에 접근 할 수 있 습 니 다.예 를 들 어 app().
두 번 째 는...
Route::get('/', function () {
dd(App::basePath());
return '';
});
// Facade, , config/app.php ,
일부 유형의 별명 을 설정 하 는 데 사용 되 는 배열 aliases 가 있 습 니 다.첫 번 째 는'app'=>Illuminate\Support\Facades\앱:class 입 니 다.구체 적 인 구 글 은 laravel 의 외관 에 대한 구체 적 인 실현 방식 을 살 펴 보 겠 습 니 다.
세 번 째 는...
서비스 제공 자 에서$this->app 을 직접 사용 합 니 다.서비스 제공 자 는 나중에 도 소개 할 것 이 고 지금 은 도입 일 뿐이다.서비스 제공 자 클래스 는 모두 laravel 용기 에 의 해 예화 되 었 기 때문에 이 클래스 들 은 Illuminate\\Support\ServiceProvider 에서 계승 되 었 습 니 다.인 스 턴 스 속성$app 을 정의 합 니 다.
abstract class ServiceProvider
{
protected $app;
예 를 들 어 laravel 은 서비스 제공 자 를 예화 할 때 laravel 용기 인 스 턴 스 를 이$app 에 주입 합 니 다.그래서 저 희 는 서비스 제공 자 에서$this->$app 을 통 해 laravel 용기 인 스 턴 스 를 방문 할 수 있 습 니 다.app()함수 나 App Facade 를 사용 하지 않 아 도 됩 니 다.어떻게 서비스 귀속 과 해석 을 이해 합 니까
『8195』얕 은 의미 차원 에서 용기 가 대상 을 저장 하 는 데 사용 되 는 이상 한 대상 이 대상 과 추출 하 는 과정 이 있어 야 한 다 는 것 을 이해 합 니 다.이 대상 을 대상 과 꺼 내 는 과정 은 laravel 에서 서비스의 바 인 딩 과 분석 이 라 고 합 니 다.
app()->bind('service', 'this is service1');
app()->bind('service2', [
'hi' => function(){
//say hi
}
]);
class Service {
}
app()->bind('service3', function(){
return new Service();
});
*8195:또 하나의 단일 바 인 딩 singleton 은 bid 의 특수 한 상황(세 번 째 매개 변 수 는 true)입 니 다.용기 에 연 결 된 대상 은 한 번 만 해석 되 고 그 후의 호출 은 모두 같은 인 스 턴 스 로 돌아 갑 니 다.
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
바 인 딩 할 때 초기 화 된 데이터(기본 형식,배열,대상 인 스 턴 스)를 직접 바 인 딩 할 수 있 고 익명 함수 로 바 인 딩 할 수 있 습 니 다.익명 함수 의 장점 은 이 서비스 가 용기 에 연 결 된 후에 서비스 최종 대상 이 즉시 발생 하지 않 고 이 서비스 가 분 석 될 때 만 익명 함수 가 실 행 됩 니 다.이때 이 서비스 에 대응 하 는 서비스 인 스 턴 스 가 생 길 수 있 습 니 다.실제 적 으로 우리 가 singleton,bid 방법 과 배열 형식 을 사용 할 때(이 세 가지 방법 은 뒤에 소개 할 바 인 딩 방법)서비스 바 인 딩 을 할 때 바 인 딩 된 서비스 형식 이 익명 함수 가 아니라면 laravel 내부 에서 익명 함수 로 포장 합 니 다.그러면 어떤 내용 을 바 인 딩 하지 않 습 니 다.앞에서 소개 한 게 으 름 초기 화 기능 을 할 수 있어 용기 의 성능 에 좋다.이것 은 bind 의 원본 코드 에서 세부 사항 을 볼 수 있 습 니 다.
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
bid 의 바 텀 코드 를 보 세 요.
public function bind($abstract, $concrete = null, $shared = false)
*8195:첫 번 째 매개 변수 서비스 바 인 딩 이름,두 번 째 매개 변수 서비스 바 인 딩 결과(즉,패 킷 을 닫 고 인 스 턴 스 를 얻 는 것)입 니 다.세 번 째 매개 변 수 는 이 서비스 가 여러 번 분석 할 때 첫 번 째 로 분 석 된 인 스 턴 스(즉,단일 바 인 딩 singleton)를 되 돌려 주 는 지 여 부 를 나타 냅 니 다.서비스 바 인 딩 은 배열 을 통 해 도 가능 합 니 다.
app()['service'] = function(){
return new Service();
};
바 인 딩 은 대략 이 정도 입 니 다.다음은 해석 을 보 겠 습 니 다.즉,꺼 내 서 사용 하 는 것 입 니 다.
$service= app()->make('service');
*8195.이 방법 은 두 개의 인 자 를 받 습 니 다.첫 번 째 는 서비스의 바 인 딩 이름과 서비스 바 인 딩 이름 의 별명 입 니 다.별명 이 라면 서비스 바 인 딩 이름 의 별명 설정 에 따라 최종 서비스 바 인 딩 이름 을 찾 아 분석 합 니 다.두 번 째 매개 변 수 는 하나의 배열 로 최종 적 으로 서비스 바 인 딩 에 의 한 패 킷 에 전 달 됩 니 다.원본 코드 보기:
/**
* 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)
);
*8195.이 방법 은 주로 분석 대상 에 매개 변수 가 있 는 지 를 구분 하 는 것 이다.만약 에 매개 변수 가 있 으 면 매개 변수 에 대해 진일보 한 분석 을 해 야 한다.들 어 오 는 매개 변수 도 주입 에 의존 할 수 있 기 때문에 들 어 오 는 매개 변 수 를 분석 해 야 한다.이 건 나중에 분석 해.두 번 째 단계:
if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
return $this->instances[$abstract];
}
『8195』바 인 딩 된 단일 사례 라면 위의 매개 변수 의존 이 필요 하지 않 습 니 다.우 리 는 바로$this->instances[$abstract]로 돌아 갈 수 있 습 니 다.세 번 째 단계:
$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;
}
*8195:이 단 계 는 주로 바 인 딩 된 문맥 에서 찾 는 것 입 니 다.바 인 딩 류 를 찾 을 수 있 습 니까?없 으 면$bings[]에서 관련 실현 류 를 찾 습 니 다.마지막 으로 찾 지 못 하면$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);
}
...
/**
* 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;
}
이전에 찾 은$concrete 가$abstract 값 을 되 돌려 주거 나$concrete 가 패키지 라면 실행 $this->build($concrete)
합 니 다.그렇지 않 으 면 패키지 의존 이 있 음 을 표시 하고 재 귀적 인 방법 으로 실행$this->make($concrete),
합 니 다.
$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 서비스 용기 의 연결 과 해석 입 니 다.여러분 께 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Laravel - 변환된 유효성 검사 규칙으로 API 요청 제공동적 콘텐츠를 위해 API를 통해 Laravel CMS에 연결하는 모바일 앱(또는 웹사이트) 구축을 고려하십시오. 이제 앱은 CMS에서 번역된 콘텐츠를 받을 것으로 예상되는 다국어 앱이 될 수 있습니다. 일반적으로 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.