Thứ Năm, Tháng Mười 28, 2021
Trang chủKiến ThứcHỏi ĐápNhà Cung Cấp Dịch Vụ ( Service Provider Là Gì ? Đặc...

Nhà Cung Cấp Dịch Vụ ( Service Provider Là Gì ? Đặc Điểm Và Vai Trò

Nếu lên google các bạn gõ Service Provider, hay Service Provider là gì, thì sau khi vào các bài viết về nó, chắc chắn các bạn sẽ nhận được những ý kiến rằng nó là một phần rất quan trọng trong Laravel. Tuy nhiên việc chỉ đọc mà không thực tế (tự tìm hiểu) thì sẽ rất khó tiếp thu cũng như hiểu được vấn đề. Vì vậy hôm nay mình cũng xin phép chia sẻ một chút thông tin mà mình tìm hiểu được qua bài viết này, đó là Service Provider trong Laravel. Sau khi đọc xong bài viết này, hi vọng các bạn có thể đưa ra quan điểm cá nhân về câu hỏi:

Service Provider là gì?. Nó quan trọng cỡ nào trong ứng dụng của chúng ta?

1. Mở đầu

Ở bài trước, mình đã viết về việc Laravel đã xử lý một request như thế nào?. Nếu như đọc bài viết của mình, hẳn các bạn cũng đã hiểu được phần nào về cách xử lý request trong Laravel. Và Service Provider cũng đã xuất hiện ở bài trước rồi. Giờ mình cùng xem Service Provider hoạt động như thế nào trong ứng dụng của chúng ta nhé.

Đang xem: Service provider là gì

2. Nội dung

Cùng quay lại một chút ở bài trước trong phần handle request, có đoạn mình có nhắc đến. Đoạn này nằm xen kẽ giữa lúc Laravel nhận request và dispatch request lên router. Đây là nơi quá trình bootstrapping bắt đầu diễn ra.

$this->bootstrap();public function bootstrap(){ if (! $this->app->hasBeenBootstrapped()) { $this->app->bootstrapWith($this->bootstrappers()); }}Bạn có thể xem nó tại IlluminateFoundationApplication.phpHàm này sẽ nạp các bootstrappers. Các bootstrappers ở đây được lấy từ trong hàm $this->bootstrappers(). Đó là những class sau:

protected $bootstrappers = < IlluminateFoundationBootstrapLoadEnvironmentVariables::class, // nạp các biến môi trường IlluminateFoundationBootstrapLoadConfiguration::class, // nạp các configuration file IlluminateFoundationBootstrapHandleExceptions::class, // nạp các file cho việc xử lý exceptions IlluminateFoundationBootstrapRegisterFacades::class, // đăng ký facade IlluminateFoundationBootstrapRegisterProviders::class, // đăng ký các service provider IlluminateFoundationBootstrapBootProviders::class, // boot>;Mở file IlluminateFoundationApplication.php và tìm đến hàm bootstrapWith ta sẽ thấy hàm này sẽ tạo ra các bootstrappers mà mình liệt kê bên trên, sau đó nạp các bootstrappers này vào trong application của bạn.

$this->make($bootstrapper)->bootstrap($this);Giờ chúng ta sẽ tìm hiểu xem Laravel Service provider hoạt động như thế nào nhé. Chúng ta biết biết chắc chắn là trong mỗi bootstrapper này đều có một hàm bootstrap.

Ở trên mình cũng giải thích lại về chức năng của từng bootstrapper này. Tuy nhiên ở đây mình sẽ đi vào class IlluminateFoundationBootstrapRegisterProviders::class để xem Service Provider đã làm những gì cho application của chúng ta:

public function bootstrap(Application $app){ $app->registerConfiguredProviders();}Ở đoạn xử lý đầu tiên, $providers của chúng ta sẽ trả về một kết quả đó là danh sách các provider nằm trong key “providers” và bắt đầu bằng Illuminate\ tại config/app.php.

Xem thêm: cách làm mặt nạ trị mụn đầu đen

$providers = Collection::make($this->config<"app.providers">) ->partition(function ($provider) { return Str::startsWith($provider, “Illuminate\”); });Ở đoạn xử lý thứ 2, Laravel sẽ gộp các providers có được tại hàm

$this->make(PackageManifest::class)->providers()vào các providers đã lấy được ở trên.Mình sẽ xem các providers trong cái hàm ở trên là những providers nào nhé. IlluminateFoundationPackageManifest.php:

public function providers(){ return collect($this->getManifest())->flatMap(function ($configuration) { return (array) ($configuration<"providers"> ?? <>); })->filter()->all();}Có vẻ hơi khó hiểu

*
Nhà Cung Cấp Dịch Vụ ( Service Provider Là Gì ? Đặc Điểm Và Vai Trò 2

. Xem hàm getManifest xem nó có gì nào ??

protected function getManifest(){ if (! is_null($this->manifest)) { return $this->manifest; } if (! file_exists($this->manifestPath)) { $this->build(); } $this->files->get($this->manifestPath, true); return $this->manifest = file_exists($this->manifestPath) ? $this->files->getRequire($this->manifestPath) : <>;}Nên nhớ ở trên chúng ta make một class PackageManifest và không truyền cho nó cái gì cả. Vậy thì constructor của nó chả có gì. Vậy là trong hàm getManifest(), property $this->manifest ở đây đang không có giá trị. Khoan đã, quay lại bài trước, các bạn để ý cho mình phần 2.2. Khởi tạo một instance từ Laravel Application có một đoạn mình có nói rằng Laravel khởi tạo một instance của PackageManifest.

$this->instance(PackageManifest::class, new PackageManifest( new Filesystem, $this->basePath(), $this->getCachedPackagesPath()));Trước hết hãy để ý một điều, Laravel sử dụng hàm này trước khi quá trình bootstrapping xuất hiện. Chi tiết các bạn hãy mở lại file public/index.php và đọc theo bài viết trước của mình, sẽ thấy thứ tự như mình nói.

Vậy lúc này trong class PackageManifest có gì ??Mình đang cần quan tâm đến hàm providers vậy nên ta cần biết tham số thứ 3 trong constructor, đó là $manifestPath là gì. Tương ứng như chúng ta thấy, đó là:

$this->getCachedPackagesPath() // bootstrap/cache/packages.phpGiờ chúng ta hiểu, giá trị $this->manifestPath chính là chuỗi bootstrap/cache/packages.php, hãy cùng tiếp tục xem Service Provider đã làm gì tiếp theo.Mở file bootstrap/cache/packages.php , chúng ta thấy 1 array chứa các cặp array khác có key là “providers” và “aliases”.Mà hàm providers của chúng ta lấy các key là “providers” Đến đây có thể hiểu rằng Laravel sẽ lấy tất cả các providers trong application của chúng ta bằng cách lấy các providers có tiền tố Illuminate\ tại config/app.php và danh sách các providers tại caches/packages.php. Sau khi tập hợp tất cả các providers chúng ta sẽ quay lại hàm registerConfiguredProviders():

(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath())) ->load($providers->collapse()->toArray());Trong hàm này, tất cả các đăng ký các event khi load các provider, sau đó các từng provider này sẽ được đăng ký bằng cách gọi đến hàm register trong class Application:

foreach ($manifest<"when"> as $provider => $events) { $this->registerLoadEvents($provider, $events);}// We will go ahead and register all of the eagerly loaded providers with the// application so their services can be registered with the application as// a provided service. Then we will set the deferred service list on it.foreach ($manifest<"eager"> as $provider) { $this->app->register($provider);}Trong hàm register tại class Application, mỗi service provider sẽ được gọi đến method register của chính provider đó.

Xem thêm: Multicast Là Gì ? Cách Hoạt Động Của Giao Thức Igmp Địa Chỉ Multicast

if (method_exists($provider, “register”)) { $provider->register();}Và nếu các bạn có để ý, trong các provider tại method register, chúng ta sẽ thường sử dụng việc binding tại hàm này, Tuy nhiên có một cách ngắn hơn đó là nếu provider của bạn đang có property là $bindings hoặc $singletons thì Laravel sẽ tự động binding theo cặp key, value này.

if (property_exists($provider, “bindings”)) { foreach ($provider->bindings as $key => $value) { $this->bind($key, $value); }}if (property_exists($provider, “singletons”)) { foreach ($provider->singletons as $key => $value) { $this->singleton($key, $value); }}// Ví dụpublic $bindings = < A::class => B::class,>; //=> $this->bind(A::class, B::class);/*** All of the container singletons that should be registered.**

RELATED ARTICLES

BÌNH LUẬN

Vui lòng nhập bình luận của bạn
Vui lòng nhập tên của bạn ở đây

Most Popular

Recent Comments