laravel服务容器 转
laravel框架底层解析
本文参考陈昊《Laravel框架关键技术解析》,搭建一个属于自己的简化版服务容器。
其中涉及到反射、自动加载,还是需要去了解一下。
laravel服务容器
建立项目空文件夹(如 mylaravel)
添加
composer.json,执行composer install
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"autoload": {
"classmap": [
],
"psr-4": {
"App\\": "app/"
}
}
}
目的是为了学习、利用composer的自动加载。
文件路径如下所示
mylaravel
app
Traveller
Traveller.php
Visit
Leg.php
Visit.php
Container.php
Index.php
vendor
composer.json
简化版
Container.php
<?php
namespace App;
Class Container
{
protected $bindings = [];
/**
* 绑定接口和生成相应实例的回调函数
* @param $abstract 服务名称
* @param null $concreate 回调函数或名称
* @param bool $shared 是否为单例
*
*/
public function bind($abstract, $concrete = null, $shared = false)
{
if ( ! $concrete instanceof \Closure) {
// 如果提供的参数不是回调函数,则产生默认的回调函数
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
}
//默认的回调函数
protected function getClosure($abstract, $concrete)
{
//生成实例的回调函数, $c一般为ioc容器对象
return function($c) use ($abstract, $concrete)
{
$method = ($abstract == $concrete) ? 'build' : 'make';
return $c->$method($concrete);
};
}
//生成实例对象,首先解决接口和要实例化类之间的依赖
public function make($abstract)
{
$concrete = $this->getConcrete($abstract);
if ($this->isBuildable($concrete, $abstract)) {
$object = $this->build($concrete);
} else {
$object = $this->make($concrete);
}
return $object;
}
protected function isBuildable($concrete, $abstract)
{
return $concrete === $abstract || $concrete instanceof \Closure;
}
//获取绑定的回调函数
protected function getConcrete($abstract)
{
if ( ! isset($this->bindings[$abstract]))
{
return $abstract;
}
return $this->bindings[$abstract]['concrete'];
}
//实例化对象
public function build($concrete)
{
if ($concrete instanceof \Closure) {
return $concrete($this);
}
$reflector = new \ReflectionClass($concrete);
if ( ! $reflector->isInstantiable()) {
echo $message = "Target [$concrete] is not instantiable.";
}
$constructor = $reflector->getConstructor();
if (is_null($constructor)) {
return new $concrete;
}
$dependencies = $constructor->getParameters();
$instances = $this->getDependencies($dependencies);
return $reflector->newInstanceArgs($instances);
}
protected function getDependencies($parameters)
{
$dependencies = [];
foreach ($parameters as $parameter)
{
$denpendency = $parameter->getClass();
if (is_null($denpendency)) {
$dependencies[] = NULL;
} else {
$dependencies[] = $this->resolveClass($parameter);
}
}
return (array) $dependencies;
}
protected function resolveClass(\ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name);
}
}
Visit.php接口
<?php
namespace App\Visit;
interface Visit
{
public function go();
}
Leg.php接口的一种实现
<?php
namespace App\Visit;
Class Leg implements Visit
{
public function go()
{
echo "walk to tibet!";
}
}
Traveller.php相当于Controller下的方法
<?php
namespace App\Traveller;
use App\Visit\Visit;
Class Traveller
{
protected $trafficTool;
//Visit是抽象类,index中将leg注入到了容器,取代了Visit
public function __construct(Visit $visit)
{
$this->trafficTool = $visit;
}
public function visitTibet()
{
$this->trafficTool->go();
}
}
Index.php
<?php
namespace App;
//调用composer的自动加载
require '../vendor/autoload.php';
Class Index
{
public function index()
{
//实例化ioc容器
$app = new Container();
//容器填充
$app->bind('App\Visit\Visit', '\App\Visit\Leg');
$app->bind('Traveller', '\App\Traveller\Traveller');
//通过容器实现依赖注入,完成类的实例化
$tra = $app->make("\App\Traveller\Traveller");
$tra->visitTibet();
}
}
$b = new Index;
$b->index();
laravel服务容器 转的更多相关文章
- Laravel 服务容器、服务提供器、契约实例讲解
前言 刚开始看laravel服务容器.契约.服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道, ...
- laravel服务容器
laravel框架底层解析 本文参考陈昊<Laravel框架关键技术解析>,搭建一个属于自己的简化版服务容器.其中涉及到反射.自动加载,还是需要去了解一下. laravel服务容器 建立项 ...
- Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)
容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器.一个容器能够装什么,全部取决于你对该容器的定义.当然,有这样一种容器,它存放的不是文本.数值,而是对象.对象的描述(类.接口)或 ...
- Laravel服务容器的绑定与解析
本篇文章给大家带来的内容是关于Laravel服务容器的绑定与解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 老实说,第一次老大让我看laravel框架手册的那天早上,我 ...
- 关于使用 Laravel 服务容器的优势介绍
如果说laravel框架的核心是什么,那么无疑是服务容器.理解服务容器的概念,对于我们使用laravel太重要了,应该说是否理解服务容器的概念是区分是否入门laravel的重要条件.因为整个框架正是在 ...
- laravel 服务容器实现原理
前言 通过实现laravel 框架功能,以便深入理解laravel框架的先进思想. 什么是服务容器 服务容器是用来管理类依赖与运行依赖注入的工具.Laravel框架中就是使用服务容器来实现 ** 控制 ...
- laravel服务容器-----深入理解控制反转(IoC)和依赖注入(DI)
首先大家想一想什么是容器,字面意思就是盛放东西的东西,常见的变量,对象属性都是容器,一个容器能够装什么东西,完全在于你对这个容器的定义.有的容器不仅仅只是存文本,变量,而是对象,属性,那么我们通过这种 ...
- Laravel 服务容器,IoC,DI
DI DI 就是常说的依赖注入,那么究竟什么是依赖注入呢? 打个比方,电脑(非笔记本哈)需要键盘和鼠标我们才能进行操作,这个‘需要’换句话说就是‘依赖’键盘和鼠标. 那么,相应的,一个类需要另一个类才 ...
- laravel 服务容器
服务容器,也叫IOC容器,其实包含了依赖注入(DI)和控制反转(IOC)两部分,是laravel的真正核心.其他的各种功能模块比如 Route(路由).Eloquent ORM(数据库 ORM 组件) ...
随机推荐
- 第1课 - 学习 Lua 的意义
第1课 - 学习 Lua 的意义 1.Lua 简介 (1) 1993年.巴西 (2) 小巧精致的脚本语言,大小只有 200K (3) 用标准C语言写成,能够在所有的平台上编译运行 (4) 发明的目标是 ...
- SpringCloud实战 | 第三篇:SpringCloud整合Nacos实现配置中心
前言 随着eureka的停止更新,如果同时实现注册中心和配置中心需要SpringCloud Eureka和SpringCloud Config两个组件;配置修改刷新时需要SpringCloud Bus ...
- 分布式文件系统之MogileFS的安装使用
一.简介 MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发:它主要由三部分组成,第一部分是server端,server端主要包括 ...
- Mysql查看最大连接,修改
1.查看最大连接量 show variables like '%max_connections%'; 2.修改最大连接量 //修改完记得重启 set GLOBAL max_connections = ...
- 217。数据中是否有重复元素(哈希表/set简法)
给定一个整数数组,判断是否存在重复元素. 如果任意一值在数组中出现至少两次,函数返回 true .如果数组中每个元素都不相同,则返回 false . 示例 1: 输入: [1,2,3,1] 输出: t ...
- 人工智能顶级会议最佳论文里的“DaDianNao”是什么鬼?
最近对人工智能领域的 AI 加速芯片感兴趣,在翻阅 Google 的第一代 TPU 论文时,在相关工作中看到了 DaDianNao,PuDianNao,ShiDianNao.看的我一脸懵逼,这是什么? ...
- 秋天的第一份“干货” I Referer 防盗链,为什么少了个字母 R?
Referer 为什么叫 Referer?它代表什么意思?在诸多防盗链竞争中它有什么优势? 今天,在聊 Referer 防盗链之前,先来聊聊我们在现实生活中常常碰到的推荐人(Referrer)信息. ...
- 如何自动填充SQL语句中的公共字段
1. 前言 我们在设计数据库的时候一定会带上新增.更新的时间.操作者等审计信息. 之所以带这些信息是因为假如有一天公司的数据库被人为删了,尽管可能有数据库备份可以恢复数据.但是我们仍然需要追踪到这个事 ...
- PageObject课程培训记录
前言 昨晚的培训课程讲了PO设计模式,对于PO模式我们需要去了解关于为什么要使用PO,而不使用PO是什么情况?什么是PO模式?PO怎么去使用? 第一,为什么要使用PO,而不使用PO是什么情况? 我们先 ...
- 为啥你用@JsonFormat注解时,LocalDateTime会反序列化失败?
写在前面 最近,有个小伙伴问我:我在SpringBoot项目中,使用@JsonFormat注解标注LocalDateTime类型的字段时,LocalDateTime反序列化失败,这个我该怎么处理呢?别 ...