云智慧(北京)科技有限公司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存储方式的时候就要经过更改业务逻辑代码才能完成。