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 组件) ...
随机推荐
- Dos拒绝服务Sockstress/TearDrop 泪滴攻击(二)
Sockstress放大攻击原理:攻击者向目标发送一个很小的流量,但是会造成产生的攻击流量是一个巨大的.成百上千倍上万倍流量被放大的一个效果,才适合作为一个拒绝服务攻击效果.(实现攻击者很小的流量打垮 ...
- hadoop和hbase高可用模式部署
记录apache版本的hadoop和hbase的安装,并启用高可用模式. 1. 主机环境 我这里使用的操作系统是centos 6.5,安装在vmware上,共三台. 主机名 IP 操作系统 用户名 安 ...
- leetcode1546题解【前缀和+贪心】
leetcode1546.和为目标值的最大数目不重叠非空子数组数目 题目链接 算法 前缀和+贪心 时间复杂度O(n). 1.对nums数组求前缀和: 2.在求前缀和过程中将前缀和sum插入到set集合 ...
- jpeg软解码实现介绍
我的月经贴博客该更新了!!!已经有许多博文需要补了! 去年开始的jpeg解码项目,中间停止更新了大半年时间,上个月想起这事还没完工,就又做了更多兼容性和性能上的改进,目前终于接近尾声了.有需要参考的可 ...
- Java基础一篇过(六)Java8--lambda表达式
一.简介 lambda表达式是Java8的一个重要特性,也可以称为闭包,常用于配合Java8的Stream对集合元素进行操作,使得代码更简介紧凑. 二.代码解析 虽说lambda表达式是一个新的特性, ...
- RocketMQ系列:rocketmq运维控制台使用详解(全网独家)
搭建好了RocketMQ的console之后,直接在浏览器打开http://{你的ip}:8080 默认会进入到驾驶舱(dashboard). 总览 整体横向菜单分为八个部分: 运维:主要是设置nam ...
- 7种jvm垃圾回收器,这次全部搞懂
前言 之前我们讲解了jvm的组成结构与垃圾回收算法等知识点,今天我们来讲讲jvm最重要的堆内存是如何使用垃圾回收器进行垃圾回收,并且如何使用命令去配置使用这些垃圾回收器. 堆内存详解 上面这个图大家应 ...
- Vue 表单拖拽排序
Vue table表单拖拽 业务需求: 因为数据展示使用的是 elementUI 的 Table进行数据展示的,现在的需求是通过拖拽表单进行表单排序.同时,动态修改表单中的数据排列顺序.查阅了好多资料 ...
- IP地址的获取
//ip地址的获取:非原创,之前在其他地方看到,拿过来备份下: public static String getIPAddress(HttpServletRequest request) { Stri ...
- CSS网页背景图片等比例占满整个页面的解决方案
想做一个个人展示类的网站首页,用整张图片来当背景,浏览器窗口放大缩小时背景图片不会变形,需要用到分层来实现其他功能,就用DIV来实现了 #bodycontainer { width:100%; hei ...