Laravel修炼:服务提供者
前言
上一篇博客文章收集了关于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修炼:服务提供者的更多相关文章
- Laravel中服务提供者和门面模式
在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel的服务提供者的方式来使用. 这两者其实区别不大,主要是前者使用的话,会跟业务代码产生依赖, ...
- Laravel服务/服务提供者/容器/契约和门面
1.服务是什么? 服务是提供了一些功能的类,比如发送邮件,写日志. 2.Laravel服务提供者是什么? 服务提供者中指明了这个提供者可以提供哪些服务(注册服务),以及服务注册后默认调用一些方法(bo ...
- Laravel修炼:服务容器绑定与解析
前言 老实说,第一次老大让我看laravel框架手册的那天早上,我是很绝望的,因为真的没接触过,对我这种渣渣来说,laravel的入门门槛确实有点高了,但还是得硬着头皮看下去(虽然到现在我还有很多 ...
- Laravel Providers——服务提供者的注册与启动源码解析
本文 GitBook 地址: https://www.gitbook.com/book/leoyang90/laravel-source-analysishttps://learnku.com/a ...
- laravel门面和服务提供者使用
关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...
- laravel 服务提供者
服务提供者,在laravel里面,其实就是一个工厂类.它最大的作用就是用来进行服务绑定.当我们需要绑定一个或多个服务的时候,可以自定义一个服务提供者,然后把服务绑定的逻辑都放在该类的实现中.在lara ...
- laravel门面与服务提供者区别
laravel门面模式与服务提供者区别 以 Laravel 自带的文件系统为例,在 config/app.php 的配置文件的 providers 数组中,注册了一个服务提供者: Illuminate ...
- laravel或者lumen门面和服务提供者使用
关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用lara ...
- [php]laravel框架容器管理的一些要点
本文面向php语言的laravel框架的用户,介绍一些laravel框架里面容器管理方面的使用要点.文章很长,但是内容应该很有用,希望有需要的朋友能看到.php经验有限,不到位的地方,欢迎帮忙指正. ...
随机推荐
- 中文版 R-FCN: Object Detection via Region-based Fully Convolutional Networks
R-FCN: Object Detection via Region-based Fully Convolutional Networks 摘要 我们提出了基于区域的全卷积网络,以实现准确和高效的目标 ...
- 手工清理win7系统C盘的技巧
在我们日常使用电脑的过程中,随着使用的时候越久,大家就会发现电脑的运行速度变的越慢了,大家都知道很多系统东西一般都会安装在C盘,系统在运行的时候就会不断的产生垃圾文件以及其他我们根本用不到的文件,这样 ...
- hiho1055/hdu1561 - 树形dp转换成背包
题目链接 输入:一棵树,每个节点一个权值. 输出:包括1号节点在内的m个节点组成的连通分量的权值和的最大值 hdu1561和hiho1055一样,只是变换了下说法 /***************** ...
- 【AnjularJS系列2 】— 表单控件功能相关指令
第二篇,表单控件功能相关指令. ng-checked控制radio和checkbox的选中状态 ng-selected控制下拉框的选中状态 ng-disabled控制失效状态 ng-multiple控 ...
- No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with name 'SpringMVC'
控制台一直报No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with na ...
- js禁止某个页面的回退
;!function(pkg, undefined){ var STATE = 'x-back'; var element; var onPopState = function(event){ eve ...
- K-D树学习笔记
这东西其实就是高维二叉树?(反正我只会二维的) 大概就是把一个高维矩形按每一维分,一个点(及其子树)就表示一个高维区间,乱搞一下,就……没了? //BZOJ4066 "简单"题 / ...
- pandas 8 画图
from __future__ import print_function import pandas as pd import numpy as np import matplotlib.pyplo ...
- Docker搭建MySQL的PXC集群
原文:Docker搭建MySQL的PXC集群 一.简介 PXC属于一套近乎完美的mysql高可用集群解决方案,相比那些比较传统的基于主从复制模式的集群架构MHA和MM+keepalived,galer ...
- 面试题——ArrayList和LinkedList的区别
List概括 先回顾一下List在Collection的框架图: 从图中可以看出: List是一个接口,他继承Collection接口,代表有序的队列. AbstractList是一个抽象类, ,它继 ...