이 페이지는 패키지 개발의 기초의 지식을 전제로 하고 있습니다. 서비스 프로바이더의 기본적인 구조를 이해한 뒤 읽는 것을 권장합니다.
왜 지연 프로바이더가 필요한가
일반적인 서비스 프로바이더는 모든 요청에서register()와 boot()가 호출됩니다. 메일 송신, 큐, 캐시 등, 모든 페이지에서 사용하지 않는 기능까지 매번 초기화하는 것은 낭비입니다.
DeferrableProvider 인터페이스
Illuminate\Contracts\Support\DeferrableProvider는 provides() 메서드 하나를 갖는 심플한 인터페이스입니다.
기본적인 구현
지연 프로바이더의 구현은 3단계입니다.1
DeferrableProvider를 implements한다
2
register()에서 서비스를 바인드한다
일반적인 프로바이더와 마찬가지로
register()에 바인드를 기술합니다.3
provides()에서 등록한 서비스를 반환한다
provides()는 register()에서 바인드한 모든 서비스를 반환해야 합니다. Laravel은 이 목록을 근거로 “어느 서비스를 요구했을 때 이 프로바이더를 로드할지”를 판단합니다.서비스 매니페스트의 구조
Laravel은 기동 시에bootstrap/cache/services.php라는 매니페스트 파일을 생성합니다. 이 파일에 지연 프로바이더가 제공하는 서비스의 목록이 보관되어 있습니다.
내부 동작의 흐름
provides() 메서드의 중요성
provides()에 등록 누락이 있으면, 그 서비스는 영원히 해결되지 않습니다.
$bindings / $singletons 프로퍼티를 사용하고 있는 경우도 마찬가지로 provides()에 포함합니다.
지연 프로바이더의 제약
지연 프로바이더는 컨테이너에의 바인딩 등록만을 목적으로 한 프로바이더에 적합합니다. 이하와 같은 것을boot()에서 하는 프로바이더는 지연화할 수 없습니다.
when() 메서드 — 이벤트 트리거에 의한 등록
when() 메서드를 사용하면, 특정 이벤트가 발화되었을 때 프로바이더를 등록할 수 있습니다. 이것은, 잡 처리계 등 특정 컨텍스트에서만 필요한 프로바이더에 사용할 수 있습니다.
when()에 반환한 이벤트가 발화되면, 서비스가 직접 해결되지 않아도 프로바이더가 로드됩니다.
패키지 개발에서의 활용
서드파티 패키지로서 배포할 때도, 지연 프로바이더는 사용자의 애플리케이션의 성능에 공헌합니다.권장 패턴
mergeConfigFrom()은 설정의 캐시 유무를 내부에서 체크하고 있으므로, 지연 프로바이더의 register() 안에서 호출해도 안전합니다. 다만 설정이 캐시된 경우에는 아무것도 하지 않습니다.runningInConsole()로 Artisan 커맨드 등록을 분리한다
커맨드 등록은 Artisan 기동 시에만 필요하므로, runningInConsole()로 조건 분기합니다. 다만 커맨드를 제공하는 프로바이더를 지연으로 하는 경우에는, 커맨드 클래스도 provides()에 포함하거나, 커맨드 전용의 프로바이더를 별도로 준비해 주세요.
Laravel 코어에서의 사용 예
Laravel의 코어 프로바이더의 다수는 지연 프로바이더입니다. 매 요청에서 사용하지 않는 서비스를 모두 즉시 로드하지 않기 위한 설계입니다.
API 엔드포인트만의 애플리케이션에서는,
MailServiceProvider나 BroadcastServiceProvider가 요청 중에 한 번도 로드되지 않는 경우도 있습니다.
지연화해야 할지의 판단 기준
지연화에 적합한 서비스
지연화에 적합한 서비스
- 모든 요청에서 사용되지는 않는 서비스(메일, 리포트, 외부 API 클라이언트 등)
- 초기화에 외부 접속이나 파일 로드가 필요한 서비스
- 무거운 오브젝트 그래프를 갖는 서비스
- CLI에서만 사용하는 커맨드를 제공하는 프로바이더
지연화에 적합하지 않은 서비스
지연화에 적합하지 않은 서비스
- 라우트를 등록하는 프로바이더(
loadRoutesFrom등) - 상시 기능하는 미들웨어나 예외 핸들러를 등록하는 프로바이더
- Eloquent의 글로벌 스코프나 옵저버를 등록하는 프로바이더
- 요청의 대부분에서 사용되는 경량 서비스(지연의 오버헤드 쪽이 커지는 경우)
관련 페이지
패키지 개발의 기초
서비스 프로바이더를 핵심으로 한 Laravel 패키지의 개발 방법을 해설합니다.
패키지의 버전 호환성 관리
Laravel과 PHP의 메이저 버전 업그레이드에 대응하는 패키지의 유지보수 전략을 해설합니다.