Featured image of post Laravel의 bind(), singleton(), scoped(), instance()의 논리적 차이점은 무엇인가요? 어떤 시나리오에서 사용할 수 있나요?

Laravel의 bind(), singleton(), scoped(), instance()의 논리적 차이점은 무엇인가요? 어떤 시나리오에서 사용할 수 있나요?

Laravel의 bind(), singleton(), scoped(), instance()의 논리적 차이점은 무엇인가요? 어떤 시나리오에서 사용할 수 있나요?

Laravel 서비스 컨테이너의 객체 바인딩 방법 비교

방법 bind() singleton() scoped() instance()
설명 해결될 때마다 새 인스턴스를 생성합니다. 인스턴스를 하나만 생성하고 후속 요청에서 동일한 인스턴스를 반환합니다. 각 요청/작업 수명 주기 내에서 인스턴스를 하나만 생성하며 요청이 끝나면 지워집니다. 기존 인스턴스를 컨테이너에 바인딩하고 해결될 때마다 해당 인스턴스를 반환합니다.
장점 - 모든 요청에 대해 새로운 인스턴스, 상태 공유 문제 없음
- 깨끗한 메모리 사용
- 독립적인 상태가 필요한 로직에 적합
- 각 요청에 대해 고유한 구성을 제공할 수 있음
- 인스턴스를 한 번만 생성하여 시스템 리소스 절약
- 상태 일관성 보장
- 구성 및 리소스 공유에 적합
- 높은 동시성 상황에서 성능이 더 좋음
- 메모리 사용량과 상태 공유의 균형
- 요청 내에서 상태를 공유하지만 요청 간에는 격리
- Web 요청 시나리오에 적합
- 인스턴스 생성 타이밍 완전 제어
- 인스턴스 상태를 미리 구성 가능
- 특정 구성이 필요한 서비스에 적합
단점 - 인스턴스를 반복적으로 생성하기 위해 더 많은 시스템 리소스 필요
- 높은 동시성 하에서 성능에 영향을 줄 수 있음
- 상태 공유가 필요한 시나리오에는 부적합
- 매번 새 인스턴스를 생성하므로 성능 문제가 발생할 수 있습니다.
- 공유 상태로 인해 추적하기 어려운 버그가 발생할 수 있음
- 독립적인 상태가 필요한 시나리오에는 부적합
- 프로그램이 종료될 때까지 메모리 사용 지속
- 테스트 시 상태 초기화에 특별한 주의 필요
- 인스턴스가 상태를 보유하고 있으면 예기치 않은 동작이 발생할 수 있습니다.
- 장기간 실행되는 작업에서 문제가 발생할 수 있음
- 요청 수명 주기 이해 필요
- CLI 명령에 부적합
- 유연성이 떨어짐
- 인스턴스 구성을 동적으로 조정할 수 없음
- 시작 시 메모리를 점유할 수 있음
- 지연 로딩이나 여러 인스턴스가 필요한 경우에는 부적합
사용 사례 단기 사용 서비스 또는 독립적인 상태가 필요한 클래스에 사용됩니다. 로거 또는 구성 관리자와 같이 전역적으로 공유되는 서비스에 사용됩니다. 데이터베이스 연결과 같이 요청 내에서 상태를 유지해야 하지만 요청 간에는 유지하지 않으려는 서비스에 사용됩니다. 공유 구성 객체와 같이 이미 인스턴스가 있고 이를 재사용하려는 경우에 사용됩니다.
예시 Product 클래스가 있고 다른 제품 데이터가 요청될 때마다 새로운 Product 인스턴스를 생성하려는 경우. Logger 클래스가 있고 일관성을 유지하기 위해 모든 로그 쓰기 작업에서 동일한 인스턴스를 사용하려는 경우. ShoppingCart 클래스가 있고 동일한 요청 내에서 장바구니 상태를 공유해야 하는 경우. DatabaseConfig 클래스가 있고 애플리케이션이 시작될 때 연결 매개변수를 설정해야 하는 경우.

예시

bind() 사용

$this->app->bind('Product', function () {
 return new Product();
});

app('Product')가 호출될 때마다 새로운 Product 인스턴스를 반환합니다.

singleton() 사용

$this->app->singleton('Logger', function () {
 return new Logger();
});

app('Logger')가 호출될 때마다 동일한 Logger 인스턴스를 반환합니다.

scoped() 사용

$this->app->scoped(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});

동일한 요청 수명 주기 내에서 동일한 인스턴스를 공유하고, 다른 요청은 새 인스턴스를 생성합니다.

instance() 사용


$service = new Transistor(new PodcastParser);
 
$this->app->instance(Transistor::class, $service);

기존 인스턴스를 컨테이너에 직접 바인딩합니다.

요약

Laravel은 현재 Web 요청, CLI 명령, Queue 작업, Console 명령 등 다양한 유형의 시나리오에 적용할 수 있습니다.

따라서 어떤 바인딩 방법을 사용할지 선택할 때는 다양한 시나리오에서 서비스의 요구 사항과 상태 또는 구성을 공유해야 하는지 여부를 고려해야 합니다.

Reference

All rights reserved,未經允許不得隨意轉載
Hugo로 만듦
JimmyStack 테마 사용 중