前言

  上一篇博客文章收集了关于Laravel服务容器的相关知识(传送门),我们知道了服务容器主要有绑定和解析两个重要功能,那么Laravel这个框架集齐了如此多功能,我们项目可能还需要另外引入一些功能包,这些绑定必须有一个统一的管理工具,统一绑定在一个地方,这个地方就是服务提供者。

关于服务提供者

  一开始学Laravel被服务容器和服务提供者两个名称搞混了,其实现在我是这样理解:容器就是底层一个大桶, 我们需要很多材料往里面填充,而提供者就是一些管道,我们就是通过提供者往容器里面塞我们需要的东西,需要的服务。

  Laravel有一种机制来定义和执行每个服务的初始处理,实现初始处理的类称为服务提供者

  服务提供者,在laravel里面,其实就是一个工厂类。它最大的作用就是用来进行服务绑定。当我们需要绑定一个或多个服务的时候,可以自定义一个服务提供者,然后把服务绑定的逻辑都放在该类的实现中。在larave里面,要自定一个服务提供者非常容易,只要继承IlluminateSupportServiceProvider这个类即可。下面通过一个简单的自定义服务提供者来说明服务提供者的一些要点:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class yourServiceProvider extends ServiceProvider
{
protected $defer = true; public function boot()
{
//
} public function register()
{
$this->app->singleton('service1', function(){
return 'service1';
});
$this->app->singleton('service2', function(){
return 'service2';
});
$this->app->singleton('service3', function(){
return 'service3';
});
} public function provides()
{
return ['service1','service2','service3'];
}
}

对于服务提供者类可以通过artisan命令创建:

artisan make:provider yourServiceProvider

创建后的文件会存放在appProviders目录下

  现在我们的服务已经在yourServiceProvider这个类里面的register()里面进行绑定了。虽然完成了服务提供者的创建和绑定,但框架现在不知道多了一个服务提供者,所以在程序运行过程中还不会调用该类中的registe()方法,所以需要在某个位置进行注册来告诉框架新创建的服务提供者--配置文件config/app.php

    'providers' => [

        /*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
...
...
...
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class, ],

当laravel找到这个服务提供者的类以后,就会初始化这个服务提供者类,得到一个服务提供者的对象,然后调用它的register方法,自然它里面的所有服务绑定代码就都会执行了:

public function registerConfiguredProviders()
{
$manifestPath = $this->getCachedServicesPath(); (new ProviderRepository($this, new Filesystem, $manifestPath))
->load($this->config['app.providers']);
}

laravel会把所有的自定义服务提供者都注册进来。这个注册的过程其实就是前面说的实例化服务提供者的类,并调用register方法的过程。

  除了register方法,服务提供者里面还有一个boot方法,这个boot方法,会在所有的服务提供者都注册完成之后才会执行,所以当你想在服务绑定完成之后,通过容器解析出其它服务,做一些初始化工作的时候,那么就可以这些逻辑写在boot方法里面。因为boot方法执行的时候,所有服务提供者都已经被注册完毕了,所以在boot方法里面能够确保其它服务都能被解析出来。

  以上主要介绍了laravel服务提供器的作用和具体使用方法,在我们平时的开发一般情况下引入第三方包就是这样的步骤(举例overtrue/laravel-wechat):

  • 安装引入:composer require "overtrue/laravel-wechat:~4.0"
  • 在 config/app.php 注册 ServiceProvider 和 Facade(Laravel 5.5 无需手动注册)
'providers' => [
// ...
Overtrue\LaravelWeChat\ServiceProvider::class,
],
'aliases' => [
// ...
'EasyWeChat' => Overtrue\LaravelWeChat\Facade::class,
],
  • 创建配置文件
artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider

服务提供者还有一个小问题值的注意,由于php是一门基本语言,在处理请求的时候,都会从入口文件把所有php都执行一遍。为了性能考虑,laravel会在第一次初始化的时候,把所有的服务提供者都缓存到bootstrap/cache/services.php文件里面,所以有时候当你改了一个服务提供者的代码以后,再刷新不一定能看到期望的效果,这有可能就是因为缓存所致。这时把services.php删掉就能看到你要的效果了。

 再次感 云诸葛这篇文章,看完后收货很大,本文内容较为粗略,想要详细了解可以看这里laravel框架容器管理的一些要点

原文地址:https://segmentfault.com/a/1190000016824040

Laravel修炼:服务提供者的更多相关文章

  1. Laravel中服务提供者和门面模式

    在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel的服务提供者的方式来使用. 这两者其实区别不大,主要是前者使用的话,会跟业务代码产生依赖, ...

  2. Laravel服务/服务提供者/容器/契约和门面

    1.服务是什么? 服务是提供了一些功能的类,比如发送邮件,写日志. 2.Laravel服务提供者是什么? 服务提供者中指明了这个提供者可以提供哪些服务(注册服务),以及服务注册后默认调用一些方法(bo ...

  3. Laravel修炼:服务容器绑定与解析

    前言   老实说,第一次老大让我看laravel框架手册的那天早上,我是很绝望的,因为真的没接触过,对我这种渣渣来说,laravel的入门门槛确实有点高了,但还是得硬着头皮看下去(虽然到现在我还有很多 ...

  4. Laravel Providers——服务提供者的注册与启动源码解析

      本文 GitBook 地址: https://www.gitbook.com/book/leoyang90/laravel-source-analysishttps://learnku.com/a ...

  5. laravel门面和服务提供者使用

      关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...

  6. laravel 服务提供者

    服务提供者,在laravel里面,其实就是一个工厂类.它最大的作用就是用来进行服务绑定.当我们需要绑定一个或多个服务的时候,可以自定义一个服务提供者,然后把服务绑定的逻辑都放在该类的实现中.在lara ...

  7. laravel门面与服务提供者区别

    laravel门面模式与服务提供者区别 以 Laravel 自带的文件系统为例,在 config/app.php 的配置文件的 providers 数组中,注册了一个服务提供者: Illuminate ...

  8. laravel或者lumen门面和服务提供者使用

      关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教.    在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用lara ...

  9. [php]laravel框架容器管理的一些要点

    本文面向php语言的laravel框架的用户,介绍一些laravel框架里面容器管理方面的使用要点.文章很长,但是内容应该很有用,希望有需要的朋友能看到.php经验有限,不到位的地方,欢迎帮忙指正. ...

随机推荐

  1. shell-3.bash的基本功能:通配符和其他特殊字符

    1. 2.

  2. SpringCloud学习笔记(2)----Spring Cloud Netflix之Eureka的使用

    1.  Spring Cloud Netflix Spring Cloud Netflix 是Spring Cloud 的核心子项目,是对Netflix公司一系列开源产品的封装.它为Spring Bo ...

  3. Dapper基础知识三

    在下刚毕业工作,之前实习有用到Dapper?这几天新项目想用上Dapper,在下比较菜鸟,这块只是个人对Dapper的一种总结. Dapper,当项目在开发的时候,在没有必要使用依赖注入的时候,如何做 ...

  4. Uncaught TypeError: Cannot read property 'offsetTop' of undefined at VueComponent.handleScroll

    mounted() { window.addEventListener("scroll", this.handleScroll); }, beforeDestroy() { win ...

  5. (WC2016模拟十八)【BZOJ4299】[CodeChef]FRBSUM

    咕了若干天我终于来补坑了qwq HINT $1\leq N,M\leq 10^5$ $1\leq \sum A_i\leq 10^9$ 题解: 虽然场上做出来了但还是觉得好神啊! 假设当前集合能凑出$ ...

  6. [UVa10188]Automated Judge Script

    题目大意:叫你写一个判断答案的系统. 解题思路:模拟即可.AC条件为,答案条数相等,所有字符相等.PE条件为,答案条数可能不等,所有数字字符相等.其他为WA. UVa现在的C++已经不支持gets了, ...

  7. 【BZOJ 1191】[HNOI2006]超级英雄Hero

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 二分图的最大匹配. 因为要答下一题,这一题必须先答完. 所以如果某道题没有匹配了. 那么就直接break掉. [代码] #inclu ...

  8. CI框架源代码阅读笔记2 一切的入口 index.php

    上一节(CI框架源代码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程.这里再次贴出流程图.以备參考: 作为CI框架的入口文件.源代码阅读,自然由此開始. 在源代码阅读的 ...

  9. iOS AES的加密解密

    主要是要得到加密后的原来的字符创,MD5无法得到原有的,仅仅能用AES+base64 要用GTMBase64这个能够自己去下载, 主要看另外2个类文件. #import <Foundation/ ...

  10. 2015百度之星初赛2 1005 序列变换(LIS变形)

    LIS(非严格):首先我想到了LIS.然而总认为有点不正确:每一个数先减去它的下标.防止以下的情况发生:(转载) 3 增加序列是1,2,2,2,3,这样求上升子序列是3.也就是要改动2个,可是中间的两 ...