Tìm kiếm bài viết

Laravel: Tìm hiểu về Service Providers

12.10.2020

0/5 (0 Reviews)

Giới thiệu về Service Providers trong laravel. Service providers là vị trí trung tâm của tất cả các ứng dụng Laravel bootstrapping.

    Giới thiệu về Service Providers trong laravel

    Service providers là vị trí trung tâm của tất cả các ứng dụng Laravel bootstrapping. Ứng dụng của bạn, cũng như các core service của Laravel được "bootstrapped" thông qua service providers.

    Nhưng, "bootstrapped" nghĩa là gì? Nói chung, chúng ý là đăng ký, bao gồm đăng kí các liên kết tới service container, event listeners, middleware, và thậm chí các route. Service providers là trung tâp để cấu hình ứng dụng của bạn.

    Nếu bạn mở file config/app.php đi kèm trong Laravel, bạn sẽ thấy một mảng providers. Tất cả những service provider class này sẽ được load vào trong ứng dụng. Tất nhiên, nhiều trong số đó được gọi là "deferred" providers, nghĩa là chúng không phải được load trong mọi request, chỉ khi có service nào yêu cầu thì mới được gọi đến.

    Trong phần tổng quát này, bạn sẽ học cách viết service providers của riêng bạn và đăng kí chúng với Laravel.

     

    Writing Service Providers

    Tất cả các service providers đều kế thừa từ class Illuminate\Support\ServiceProvider. Hầu hết service providers chứa phương thức registerboot. Trong phương thức register, bạn nên only bind things into the . Bạn đừng bao giờ cố gắng đăng kí bất kì các event listeners, routes hay bất kì chức năng nào khác vào trong phương thức register.

     

    Artisan CLI có thể dễ dàng sinh ra một provider mới thông qua lệnh make:provider:

     

    php artisan make:provider RiakServiceProvider
    

    The Register Method

    Như đã đề cập ở trước, bên trong phương thức register, bạn chỉ bind mọi thứ vào trong . Bạn đừng bao giờ cố gắng đăng ký bất kỳ event listeners, routes hay bất kì các chức năng nào khác vào trong phương thức register. Nếu không, bạn vô tình có thể sử dụng một service được cung cấp bởi một service provider mà chưa được load.

     

    Hãy xem một ví dụ service provider cơ bản bên dưới. Trong bất kỳ phương thức nào của service provider, bạn luôn có quyền truy cập vào thuộc tính $app, nó cung cấp quyền để truy cập vào service container:

     

    <?php
    
    namespace App\Providers;
    
    use Riak\Connection;
    use Illuminate\Support\ServiceProvider;
    
    class RiakServiceProvider extends ServiceProvider
    {
        /**
         * Register bindings in the container.
         *
         * @return void
         */
        public function register()
        {
            $this->app->singleton(Connection::class, function ($app) {
                return new Connection(config('riak'));
            });
        }
    }
    

     

    Service provider này chỉ định nghĩa 1 phương thức register, và sử dụng phương twhcs đó để define một implementation của Riak\Connection trong service container. Nếu bạn không hiểu service container hoạt động như thế nào, hãy xem này.

     

    ThebindingsAndsingletonsProperties

     

    Nếu service provider của bạn đăng ký nhiều rằng buộc đơn giản, bạn có thể muốn sử dụng thuộc tính bindingssingletons thay vì đăng ký thủ công từng container binding. Khi service provider được load bởi framework, nó sẽ tự động kiểm tra cá thuộc tính này và đăng ký các binding của chúng:

     

    <?php
    
    namespace App\Providers;
    
    use App\Contracts\ServerProvider;
    use App\Contracts\DowntimeNotifier;
    use Illuminate\Support\ServiceProvider;
    use App\Services\PingdomDowntimeNotifier;
    use App\Services\DigitalOceanServerProvider;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * All of the container bindings that should be registered.
         *
         * @var array
         */
        public $bindings = [
            ServerProvider::class => DigitalOceanServerProvider::class,
        ];
    
        /**
         * All of the container singletons that should be registered.
         *
         * @var array
         */
        public $singletons = [
            DowntimeNotifier::class => PingdomDowntimeNotifier::class,
        ];
    }
    

    The Boot Method

    Vậy nếu như chúng ta muốn đăng kí một vào trong service provider thì sao? Điều này có thể thực hiện bên trong phương thức boot. Phương thức này được gọi sau khi tất cả các service providers đã được đăng kí, nghĩa là bạn có thể truy cập vào trong tất cả các services đã được đăng kí vào trong framework:

     

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class ComposerServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            view()->composer('view', function () {
                //
            });
        }
    }
    

     

    Boot Method Dependency Injection

     

    Bạn có thể type-hint dependencies cho service provider của bạn ở phương thức boot. sẽ tự động inject bất cứ dependencies nào bạn cần:

     

    use Illuminate\Contracts\Routing\ResponseFactory;
    
    public function boot(ResponseFactory $response)
    {
        $response->macro('caps', function ($value) {
            //
        });
    }
    

    Registering Providers

    Tất cả các service provider được đăng kí bên trong file cấu hình config/app.php. File này chứa một mảng providers nơi mà bạn có thể liệt kê tên class của các service providers. Mặc định, một tập hợp các core service provider của Laravel nằm trong mảng này. Những provider này làm nhiệm vụ khởi tạo các thành phần core của Laravel, ví dụ như mailer, queue, cache, và các thành phần khác.

     

    Để đăng ký provider của bạn, thêm nó vào mảng:

     

    'providers' => [
        // Other Service Providers
    
        App\Providers\ComposerServiceProvider::class,
    ],
    

    Deferred Providers

    Nếu provider của bạn chỉ đăng ký các bindings trong , bạn có thể chọn trì hoãn việc đăng kí của mình cho tới khi nào cần thiết. Việc trì hoãn quá trình load một provider sẽ cải thiện performance cho ứng dụng, vì nó không load từ filesystem cho mọi request.

     

    Laravel biên dịch và lưu một danh sách tất cả các services cung cấp bởi deferred service providers, cùng với tên class service provider của nó. Khi đó, chỉ khi nào bạn cần resolve một trong những service này thì Laravel mới thực hiện load service provider.

     

    Để trì hoàn việc load một provider, set thuộc tính defer thành true và định nghĩa một phương thức provides. Phương thức provides sẽ trả về binding service container mà provider này đăng kí:

    <?php
    
    namespace App\Providers;
    
    use Riak\Connection;
    use Illuminate\Support\ServiceProvider;
    
    class RiakServiceProvider extends ServiceProvider
    {
        /**
         * Indicates if loading of the provider is deferred.
         *
         * @var bool
         */
        protected $defer = true;
    
        /**
         * Register the service provider.
         *
         * @return void
         */
        public function register()
        {
            $this->app->singleton(Connection::class, function ($app) {
                return new Connection($app['config']['riak']);
            });
        }
    
        /**
         * Get the services provided by the provider.
         *
         * @return array
         */
        public function provides()
        {
            return [Connection::class];
        }
    
    }
    
    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết