亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

laravel中Container依賴注入,多次生成類實例

laravel中Container依賴注入,多次生成類實例

PHP
拉莫斯之舞 2019-03-18 15:28:25
看laravel中Comtroller發現,類依賴注入時,當我通過make創建對象時,發現依賴被創建了多份實例。 代碼如下: <?php namespace Tests\Unit; use Illuminate\Container\Container; use Tests\TestCase; interface SessionStorage { public function get($key); public function set($key, $value); } class FileSessionStorage implements SessionStorage { public function __construct() { echo "file init \n"; } public function get($key) { // TODO: Implement get() method. } public function set($key, $value) { // TODO: Implement set() method. } } class MySqlSessionStorage implements SessionStorage { public function __construct() { echo "mysql init \n"; } public function get($key) { // TODO: Implement get() method. } public function set($key, $value) { // TODO: Implement set() method. } } class SimpleAuth { protected $session; public function __construct(SessionStorage $session) { $this->session = $session; } public function get() { $this->session->get(null); } } class ExampleTest extends TestCase { /** * A basic test example. * * @return void */ public function testBasicTest() { $container = Container::getInstance(); $container->bind( SessionStorage::class, MysqlSessionStorage::class ); $container->make(SimpleAuth::class); echo "-\n"; $container->bind( SessionStorage::class, FileSessionStorage::class ); $container->make(SimpleAuth::class); echo "-\n"; $container->bind( SessionStorage::class, MysqlSessionStorage::class ); $container->make(SimpleAuth::class); } } 代碼的輸出結果如下: 跟預期不同的地方: 第一次make操作的時候,通過構造函數的輸出,可以看出,依賴關系僅僅被實例化了一次 但后面再次調用bind,make發現構造函數被調用了兩次 mysql init - file init file init - mysql init mysql init 嘗試debug:在make函數中記錄調用的次數。: public function make($abstract, array $parameters = []) { if (stripos($abstract, 'SessionStorage') !== false) { echo "make plus \n"; } return $this->resolve($abstract, $parameters); } =================== 輸出結果 ================= make plus make plus mysql init - make plus make plus file init make plus make plus file init - make plus make plus mysql init make plus make plus mysql init 怎么破?。?!
查看完整描述

2 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

跟一下源碼,能找到問題:
1、bind()調用時,會把bind的abstract放在bindings數組中;
2、make()調用時,其實調用resolve,如果是單例(singleton)就會在instances中,查到返回就是單例,直接bind的不是單例,所以每次調用會有切僅有一次構造函數調用;
3、但是為啥調用了多次,問題在于第二次bind()的時候,因為前面已經make()過(也就是resolve過),所以在bind()函數的最后,會調用rebound()函數,在rebound()函數中會實例化一個abstract用于調用rebound的回調;
4、所以,并不是第二次make()的時候調用了兩次實例化,而是第二次bind()一次,第二次make()一次;因為第二次bind的時候,會觸發rebound;

(PS:不知道為啥我上傳圖片一直失敗。。。將就看文字吧)

查看完整回答
反對 回復 2019-03-18
  • 2 回答
  • 0 關注
  • 816 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號