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 组件) ...
随机推荐
- django.db.utils.InternalError: (1091, "Can't DROP 'cre_time'; check that column/key exists")
在执行命令python manage.py migrate时报错:django.db.utils.InternalError: (1091, “Can’t DROP ‘cre_time’; check ...
- linux系统的默认用户
1.可以通过cat /etc/passwd |cut -f1 -d: 可以提取/etc/passwd文件的第一个字段 2.也可以通过vipw进入vi编辑器来查看该文件每一行的第一个字段 linux ...
- 《C语言进阶剖析》课程目录
<C语言进阶剖析>学习笔记 本文总结自狄泰软件学院唐佐林老师的<C语言 ...
- 高可用集群之keepalived+lvs实战2
keepalived简介 lvs在我之前的博客<高负载集群实战之lvs负载均衡-技术流ken>中已经进行了详细的介绍和应用,在这里就不再赘述.这篇博文将把lvs与keepalived相结合 ...
- java的注解学习
转载自https://www.cnblogs.com/xdp-gacl/p/3622275.html 孤傲苍狼 只为成功找方法,不为失败找借口! Java基础加强总结(一)——注解(Annotatio ...
- hystrix文档翻译之工作原理
流程图 下面的图片显示了一个请求在hystrix中的流程图. 1.构造一个HystrixCommand或者HystrixObservableCommand对象 第一步是创建一个HystrixComma ...
- C# NX二次开发环境搭建
在网上看到一篇C#二次开发环境搭建的文章:NX二次开发-使用NXOPEN C#手工搭建开发环境配置 ,写得非常好.我按照文章操作,过程中遇到几个问题,把问题分享给大家,希望对各位有帮助. 注意三点: ...
- 多NX如何共存
在安装NX时,本机已经装了NX其他版本,只能修改当前程序,无法安装,那么多NX如何共存? 如图:先安装了32位NX8.5,后安装64位NX 8.5时弹的框. 解决办法有两种: 1)将已经安装的NX目录 ...
- [0CTF 2016]piapiapia(反序列逃逸)
我尝试了几种payload,发现有两种情况. 第一种:Invalid user name 第二种:Invalid user name or password 第一步想到的是盲注或者报错,因为fuzz一 ...
- 使用IDEA远程调试SpringBoot程序
远程调试就是服务端程序运行在一台远程服务器上,我们在本地服务端的代码中设置断点(本地的代码必须与远端一致),进行调试.每当有请求到达远程服务器时能够在本地知道远端程序的运行情况. 1.点击Run 选择 ...