雲智慧(北京)科技有限公司php
1、IoC的概念介紹laravel
控制反轉(IOC)模式(又稱DI:DependencyInjection)就是Inversion ofControl,控制反轉。在Java開發中,IoC意 味着將你設計好的類交給系統去控制,而不是在你的類內部控制。這稱爲控制反轉。redis
IoC(Inversion of Control)是近年來興起的一種思想,不單單是編程思想。主要是協調各組件間相互的依賴關係,同時大大提升了組件的可移植性,組件的重用機會也變得更多。在傳統的實現中,由程序內部代碼來控制程序之間的關係。咱們常常使用new關鍵字來實現兩組鍵間關係的組合,這種實現的方式會形成組件之間耦合(一個好的設計,不但要實現代碼重用,還要將組件間關係解耦)。IoC很好的解決了該問題,它將實現組件間關係從程序內部提到外部容器來管理。也就是說由容器在運行期將組件間的某種依賴關係動態的注入組件中。控制程序間關係的實現交給了外部的容器來完成。即常說的好萊塢原則「Don't call us, we'll call you」。編程
那麼,在Laravel框架中Ioc模式是如何實現的呢?數組
2、Laravel框架中Ioc模式的實現方式緩存
1.請求實現的流程圖app
在請求流程圖中能夠看到有兩個比較重要的文件start.php和Application.php,其中,start.php文件中引入了全局變量$app = new Illuminate\Foundation\Application;注意該全局變量$app就是爲咱們解決全部注入依賴關係的「管家婆」,它會把應用中所用到的工具類提早存儲起來,當用到的時候能夠隨時的提取。框架
2.採用數組的方式管理對象ide
lluminate\Foundation\Application類繼承了laravel的容器Container和php的標準接口ArrayAccess,從而實現了數組方式管理對象。工具
php的標準接口ArrayAccess中包含了四個屬性:
下面是ArrayAccess 的定義:
interface ArrayAccess
boolean offsetExists($index)
mixed offsetGet($index)
void offsetSet($index, $newvalue)
void offsetUnset($index)
Application類中繼承的container類對這四個抽象方法進行了重寫,實現了應用中所用到的功能。Container類中的兩個屬性$bindings和$instances是用來存放實際應用中所用到的工具類實例。這樣咱們就能夠經過$app[‘工具類的別名’]或者經過「工具類的別名::方法名」的方式來調用真正的工具類實例中的方法。
列如,路由中經常使用的方式: Route::post(‘url’,’controller@method’);
將服務註冊到$app全局變量中,laravel的實現方式是讀取app/config/app.php配置,並將
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
'Illuminate\Session\CommandsServiceProvider',
'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
'Illuminate\Routing\ControllerServiceProvider',
'Illuminate\Cookie\CookieServiceProvider',
'Illuminate\Database\DatabaseServiceProvider',
'Illuminate\Encryption\EncryptionServiceProvider',
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Illuminate\Log\LogServiceProvider',
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
'Illuminate\Queue\QueueServiceProvider',
'Illuminate\Redis\RedisServiceProvider',
'Illuminate\Remote\RemoteServiceProvider',
'Illuminate\Auth\Reminders\ReminderServiceProvider',
'Illuminate\Database\SeedServiceProvider',
'Illuminate\Session\SessionServiceProvider',
'Illuminate\Translation\TranslationServiceProvider',
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Workbench\WorkbenchServiceProvider',
),
經過\Illuminate\Foundation\start.php文件中的
$providers = $config['providers'];
$app->getProviderRepository()->load($app,$providers);
注入到$app中。同時,在該文件中還會執行
$aliases = $config['aliases'];
AliasLoader::getInstance($aliases)->register();
這樣就能夠實現使用別名訪問想要運行的服務了。
利用控制反轉和別名的好處:
Laravel中經過控制反轉的方式能夠解決相同的調用方式,但能夠採起不一樣的實現方式。這樣咱們就不用更改業務邏輯中的代碼,就能更換不一樣的解決問題的方式。
例如,Laravel用到的Cache,在業務邏輯代碼中只須要使用Cache::set(),就能夠設置cache緩存了。可是,具體是用什麼方式作的cache咱們是不用關心的。由於,$app[‘cache’]中便可以存放redis的實例,也能夠存放memcache的實例,這個是能夠經過配置文件來肯定的。
若是要是用傳統的cache方式,將會是Redis::set()或者是Memcache::set()的方式,這樣咱們在想換不一樣的cache存儲方式的時候就要經過更改業務邏輯代碼才能完成。