精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Laravel學習筆記之Container源碼解析

開發(fā) 前端
本文主要學習Laravel中Container的源碼,主要學習Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對別人有所幫助。下面聊聊自動解析過程,研究下Container是如何在自動解析Service時解決該Service的依賴問題的。

說明:本文主要學習Laravel中Container的源碼,主要學習Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對別人有所幫助。實際上Container的綁定主要有三種方式:bind(),singleton(),instance(),且singleton()只是一種'shared' = true的bind(),這些已經(jīng)在Laravel學習筆記之IoC Container實例化源碼解析聊過,其實現(xiàn)方法并不復雜。當Service通過Service Provider綁定到Container中后,當需要該Service時,是需要Container幫助自動解析make()。OK,下面聊聊自動解析過程,研究下Container是如何在自動解析Service時解決該Service的依賴問題的。

開發(fā)環(huán)境: Laravel5.3 + PHP7 + OS X 10.11

PHPUnit測試下綁定

在聊解析過程前,先測試下\Illuminate\Container\Container中綁定的源碼,這里測試下bind(),singleton(),instance()三個綁定方式: 

  1. <?php 
  2.  
  3. namespace MyRightCapital\Container\Tests; 
  4.  
  5. use MyRightCapital\Container\Container; 
  6.  
  7. class ContainerBindTest extends \PHPUnit_Framework_TestCase 
  8.     /** 
  9.      * @var Container $container 
  10.      */ 
  11.     protected $container; 
  12.  
  13.     public function setUp() 
  14.     { 
  15.         $this->container = new Container(); 
  16.     } 
  17.  
  18.     public function testBindClosure() 
  19.     { 
  20.         // Arrange 
  21.         $expected = 'Laravel is a PHP Framework.'
  22.         $this->container->bind('PHP'function () use ($expected) { 
  23.             return $expected; 
  24.         }); 
  25.  
  26.         // Actual 
  27.         $actual = $this->container->make('PHP'); 
  28.  
  29.         // Assert 
  30.         $this->assertEquals($expected, $actual); 
  31.     } 
  32.  
  33.     public function testBindInterfaceToImplement() 
  34.     { 
  35.         // Arrange 
  36.         $this->container->bind(IContainerStub::class, ContainerImplementationStub::class); 
  37.  
  38.         // Actual 
  39.         $actual = $this->container->make(IContainerStub::class); 
  40.  
  41.         // Assert 
  42.         $this->assertInstanceOf(IContainerStub::class, $actual); 
  43.     } 
  44.  
  45.     public function testBindDependencyResolution() 
  46.     { 
  47.         // Arrange 
  48.         $this->container->bind(IContainerStub::class, ContainerImplementationStub::class); 
  49.  
  50.         // Actual 
  51.         $actual = $this->container->make(ContainerNestedDependentStub::class); 
  52.  
  53.         // Assert 
  54.         $this->assertInstanceOf(ContainerDependentStub::class, $actual->containerDependentStub); 
  55.         $this->assertInstanceOf(ContainerImplementationStub::class, $actual->containerDependentStub->containerStub); 
  56.     } 
  57.  
  58.     public function testSingleton() 
  59.     { 
  60.         // Arrange 
  61.         $this->container->singleton(ContainerConcreteStub::class); 
  62.         $expected = $this->container->make(ContainerConcreteStub::class); 
  63.  
  64.         // Actual 
  65.         $actual = $this->container->make(ContainerConcreteStub::class); 
  66.  
  67.         // Assert 
  68.         $this->assertSame($expected, $actual); 
  69.     } 
  70.  
  71.     public function testInstanceExistingObject() 
  72.     { 
  73.         // Arrange 
  74.         $expected = new ContainerImplementationStub(); 
  75.         $this->container->instance(IContainerStub::class, $expected); 
  76.  
  77.         // Actual 
  78.         $actual = $this->container->make(IContainerStub::class); 
  79.  
  80.         // Assert 
  81.         $this->assertSame($expected, $actual); 
  82.     } 
  83.  
  84. class ContainerConcreteStub 
  85.  
  86.  
  87. interface IContainerStub 
  88.  
  89.  
  90. class ContainerImplementationStub implements IContainerStub 
  91.  
  92.  
  93. class ContainerDependentStub 
  94.     /** 
  95.      * @var \MyRightCapital\Container\Tests\IContainerStub 
  96.      */ 
  97.     public $containerStub; 
  98.  
  99.     public function __construct(IContainerStub $containerStub) 
  100.     { 
  101.         $this->containerStub = $containerStub; 
  102.     } 
  103.  
  104. class ContainerNestedDependentStub 
  105.     /** 
  106.      * @var \MyRightCapital\Container\Tests\ContainerDependentStub 
  107.      */ 
  108.     public $containerDependentStub; 
  109.  
  110.     public function __construct(ContainerDependentStub $containerDependentStub) 
  111.     { 
  112.         $this->containerDependentStub = $containerDependentStub; 
  113.     } 

 這里測試了bind()綁定閉包,綁定接口和對應實現(xiàn),依賴解析這三個feature,singleton()測試了是否為單例綁定一個feature,instance()測試了已存在對象綁定這個feature,測試結果5個tests都通過:

 關于在PHPStorm中配置PHPUnit可參考這篇:Laravel學習筆記之基于PHPStorm編輯器的Laravel開發(fā)

make()源碼解析

從以上testcase知道,make()是負責從Container中解析出service的,而且在testBindDependencyResolution()這個test中,還能發(fā)現(xiàn)當ContainerNestedDependentStub::class有構造依賴時,Container也會自動去解析這個依賴并注入ContainerNestedDependentStub::class的構造函數(shù)中,這個依賴是ContainerDependentStub::class,而這個依賴又有自己的依賴IContainerStub::class,從斷言語句$this->assertInstanceOf(ContainerImplementationStub::class, $actual->containerDependentStub->containerStub);知道,Container又自動解析了這個依賴,所有這一切都不需要我們手動去解析,全都是Container自動化解析的。

這一切Container是怎么做到的?實際上并不復雜,解決依賴只是用了PHP的Reflector反射機制來實現(xiàn)的。先看下make()源碼: 

  1. /** 
  2.      * Resolve the given type from the container. 
  3.      * 
  4.      * @param  string  $abstract 
  5.      * @param  array   $parameters 
  6.      * @return mixed 
  7.      */ 
  8.     public function make($abstract, array $parameters = []) 
  9.     { 
  10.         $abstract = $this->getAlias($this->normalize($abstract)); 
  11.  
  12.         // 如果是instance()綁定的方式,就直接解析返回綁定的service 
  13.         if (isset($this->instances[$abstract])) { 
  14.             return $this->instances[$abstract]; 
  15.         } 
  16.  
  17.         // 獲取$abstract對應綁定的$concrete 
  18.         $concrete = $this->getConcrete($abstract); 
  19.  
  20.         if ($this->isBuildable($concrete, $abstract)) { 
  21.             $object = $this->build($concrete, $parameters); 
  22.         } else { 
  23.             $object = $this->make($concrete, $parameters); 
  24.         } 
  25.  
  26.         foreach ($this->getExtenders($abstract) as $extender) { 
  27.             $object = $extender($object, $this); 
  28.         } 
  29.  
  30.         if ($this->isShared($abstract)) { 
  31.             $this->instances[$abstract] = $object; 
  32.         } 
  33.  
  34.         $this->fireResolvingCallbacks($abstract, $object); 
  35.  
  36.         $this->resolved[$abstract] = true
  37.  
  38.         return $object; 
  39.     } 
  40.      
  41.     protected function getConcrete($abstract) 
  42.     { 
  43.         if (! is_null($concrete = $this->getContextualConcrete($abstract))) { 
  44.             return $concrete; 
  45.         } 
  46.  
  47.         // 如果是$this->container->singleton(ContainerConcreteStub::class);這種方式綁定,即$concrete = null 
  48.         // 則 $abstract = $concrete,可看以上PHPUnit的testSingleton()這個test 
  49.         // 這種方式稱為'自動補全'綁定 
  50.         if (! isset($this->bindings[$abstract])) { 
  51.             return $abstract; 
  52.         } 
  53.  
  54.         return $this->bindings[$abstract]['concrete']; 
  55.     } 
  56.      
  57.     protected function isBuildable($concrete, $abstract) 
  58.     { 
  59.         return $concrete === $abstract || $concrete instanceof Closure; 
  60.     }  

從以上源碼可知道如果綁定的是閉包或者'自動補全'綁定($concrete = null),則需要build()這個閉包或類名,轉換成對應的實例。如果是'接口實現(xiàn)'這種方式綁定,則需要再一次調用make()并經(jīng)過getConcrete后$abstract = $concrete,然后符合isBuildable()的條件,進入build()函數(shù)內。所以以上的PHPUnit的測試用例中不管什么方式的綁定,都要進入build()函數(shù)內編譯出相應對象實例。當編譯出對象后,檢查是否是共享的,以及是否要觸發(fā)回調,以及標記該對象已經(jīng)被解析。OK,看下build()的源碼: 

  1. /** 
  2.      * Instantiate a concrete instance of the given type. 
  3.      * 
  4.      * @param  string  $concrete 
  5.      * @param  array   $parameters 
  6.      * @return mixed 
  7.      * 
  8.      * @throws \Illuminate\Contracts\Container\BindingResolutionException 
  9.      */ 
  10.     public function build($concrete, array $parameters = []) 
  11.     { 
  12.         // 如果是閉包直接執(zhí)行閉包并返回,e.g. PHPUnit的這個test:testBindClosure() 
  13.         if ($concrete instanceof Closure) { 
  14.             return $concrete($this, $parameters); 
  15.         } 
  16.          
  17.         // 如這個test:testBindInterfaceToImplement(),這里的$concrete = ContainerImplementationStub::class類名稱, 
  18.         // 則使用反射ReflectionClass來探測ContainerImplementationStub這個類的構造函數(shù)和構造函數(shù)的依賴 
  19.         $reflector = new ReflectionClass($concrete); 
  20.  
  21.         // 如果ContainerImplementationStub不能實例化,這應該是接口或抽象類,再或者就是ContainerImplementationStub的構造函數(shù)是private的 
  22.         if (! $reflector->isInstantiable()) { 
  23.             if (! empty($this->buildStack)) { 
  24.                 $previous = implode(', ', $this->buildStack); 
  25.  
  26.                 $message = "Target [$concrete] is not instantiable while building [$previous]."
  27.             } else { 
  28.                 $message = "Target [$concrete] is not instantiable."
  29.             } 
  30.  
  31.             throw new BindingResolutionException($message); 
  32.         } 
  33.  
  34.         $this->buildStack[] = $concrete; 
  35.  
  36.         // 獲取構造函數(shù)的反射 
  37.         $constructor = $reflector->getConstructor(); 
  38.  
  39.         // 如果構造函數(shù)是空,說明沒有任何依賴,直接new返回 
  40.         if (is_null($constructor)) { 
  41.             array_pop($this->buildStack); 
  42.  
  43.             return new $concrete; 
  44.         } 
  45.          
  46.         // 獲取構造函數(shù)的依賴,返回ReflectionParameter[] 
  47.         $dependencies = $constructor->getParameters(); 
  48.  
  49.         $parameters = $this->keyParametersByArgument( 
  50.             $dependencies, $parameters 
  51.         ); 
  52.  
  53.         // 然后就是獲取相關依賴,如testBindDependencyResolution()這個test中, 
  54.         // ContainerNestedDependentStub::class是依賴于ContainerDependentStub::class的 
  55.         $instances = $this->getDependencies( 
  56.             $dependencies, $parameters 
  57.         ); 
  58.  
  59.         array_pop($this->buildStack); 
  60.  
  61.         return $reflector->newInstanceArgs($instances); 
  62.     }  

從源碼可知道,比較麻煩的是當ContainerNestedDependentStub::class的構造函數(shù)有依賴ContainerDependentStub::class時,通過getDependencies()來解決的,看下getDependencies()的源碼: 

  1. // 這里$parameters = ReflectionParameter[] 
  2.     protected function getDependencies(array $parameters, array $primitives = []) 
  3.     { 
  4.         $dependencies = []; 
  5.  
  6.         foreach ($parameters as $parameter) { 
  7.             $dependency = $parameter->getClass(); 
  8.  
  9.             // 如果某一依賴值已給,就賦值 
  10.             if (array_key_exists($parameter->name, $primitives)) { 
  11.                 $dependencies[] = $primitives[$parameter->name]; 
  12.             }  
  13.             // 如果類名為null,說明是基本類型,如'int','string' and so on
  14.             elseif (is_null($dependency)) { 
  15.                 $dependencies[] = $this->resolveNonClass($parameter); 
  16.             }  
  17.             // 如果是類名,如ContainerDependentStub::class,則resolveClass去解析成對象 
  18.             else { 
  19.                 $dependencies[] = $this->resolveClass($parameter); 
  20.             } 
  21.         } 
  22.  
  23.         return $dependencies; 
  24.     }  

通過上面注釋,看下resolveClass()的源碼: 

  1. protected function resolveClass(ReflectionParameter $parameter) 
  2.    { 
  3.        try { 
  4.            // $parameter->getClass()->name返回的是類名,如ContainerNestedDependentStub依賴于$containerDependentStub 
  5.            // $containerDependentStub的typehint是ContainerDependentStub,所以類名是'ContainerDependentStub' 
  6.            // 然后遞歸繼續(xù)make(ContainerDependentStub::class) 
  7.            // 又和PHPUnit中這個測試$this->container->make(ContainerNestedDependentStub::class)相類似了 
  8.            // ContainerNestedDependentStub又依賴于IContainerStub::class, 
  9.            // IContainerStub::class是綁定于ContainerImplementationStub::class 
  10.            // 直到ContainerImplementationStub沒有依賴或者是構造函數(shù)是基本屬性, 
  11.            // ***build()結束 
  12.            return $this->make($parameter->getClass()->name); 
  13.        } catch (BindingResolutionException $e) { 
  14.            if ($parameter->isOptional()) { 
  15.                return $parameter->getDefaultValue(); 
  16.            } 
  17.  
  18.            throw $e; 
  19.        } 
  20.    }  

從以上代碼注釋直到build()是個遞歸過程,A類依賴于B類,B類依賴于C類和D類,那就從A類開始build,發(fā)現(xiàn)依賴于B類,再從Container中解析make()即再build()出B類,發(fā)現(xiàn)依賴于C類,再make() and build(),發(fā)現(xiàn)B類又同時依賴于D類,再make() and build(),以此類推直到?jīng)]有依賴或依賴基本屬性,解析結束。這樣一步步解析完后,發(fā)現(xiàn)Container的解析make()并不是很神秘很復雜中的過程。

從以上源碼發(fā)現(xiàn)PHP的反射Reflector是個很好用的技術,這里給出個test,看下Reflector能干些啥: 

  1. <?php 
  2.  
  3. class ConstructorParameter 
  4.  
  5.  
  6. class ReflectorTest 
  7.     private $refletorProperty1; 
  8.  
  9.     protected $refletorProperty2; 
  10.  
  11.     public $refletorProperty3; 
  12.  
  13.     /** 
  14.      * @var int 
  15.      */ 
  16.     private $request; 
  17.  
  18.     public function __construct(int $request = 10, string $response, ConstructorParameter $constructorParameter, Closure $closure) 
  19.     { 
  20.  
  21.         $this->request = $request; 
  22.     } 
  23.  
  24.     private function reflectorMethod1() 
  25.     { 
  26.     } 
  27.  
  28.     protected function reflectorMethod2() 
  29.     { 
  30.     } 
  31.  
  32.     public function reflectorMethod3() 
  33.     { 
  34.     } 
  35.  
  36. $reflector_class        = new ReflectionClass(ReflectorTest::class); 
  37. $methods                = $reflector_class->getMethods(); 
  38. $properties             = $reflector_class->getProperties(); 
  39. $constructor            = $reflector_class->getConstructor(); 
  40. $constructor_parameters = $constructor->getParameters(); 
  41.  
  42. foreach ($constructor_parameters as $constructor_parameter) { 
  43.     $dependency = $constructor_parameter->getClass(); 
  44.     var_dump($dependency); 
  45.  
  46.     if ($constructor_parameter->isDefaultValueAvailable()) { 
  47.         var_dump($constructor_parameter->getDefaultValue()); 
  48.     } 
  49.  
  50. var_dump($methods); 
  51. var_dump($properties); 
  52. var_dump($constructor); 
  53. var_dump($constructor_parameters);  

打印結果太長了,就不粘貼了。可以看下PHP官方文檔:Reflector

總結:本文學習了下Container的核心功能:service resolve的過程,并學習了service的依賴是如何被自動解析的。遇到好的心得再分享,到時見。

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2016-09-20 10:26:25

LaravelPHPMiddleware

2016-09-21 21:49:37

PromiseJavascript前端

2011-04-22 14:14:21

MySQL偷窺線程

2021-02-20 06:09:46

libtask協(xié)程鎖機制

2010-07-27 15:42:18

AdobeFlex

2010-06-12 13:08:51

UML全稱

2022-02-14 14:47:11

SystemUIOpenHarmon鴻蒙

2022-12-07 08:02:43

Spring流程IOC

2016-12-15 09:44:31

框架Caffe源碼

2011-03-08 16:30:24

Proftpd

2011-03-08 16:30:40

Proftpd

2010-06-13 12:49:23

UML及建模

2011-09-01 14:14:00

jQuery Mobi

2010-06-28 15:41:17

UML圖類型

2010-06-28 18:44:54

UML對象圖

2022-08-08 08:03:44

MySQL數(shù)據(jù)庫CBO

2022-05-17 10:42:36

reboot源碼解析

2017-06-07 14:58:39

Redis源碼學習Redis事務

2012-02-23 11:06:18

JavaPlay FramewPlay!

2010-06-28 18:36:06

UML協(xié)作圖
點贊
收藏

51CTO技術棧公眾號

国产精品入口免费视| 亚洲欧美日韩中文在线制服| 91精品国产吴梦梦| 国产成人手机在线| 日韩成人伦理电影在线观看| 久久天天躁狠狠躁夜夜躁| 中国免费黄色片| 四虎国产精品永久在线国在线 | 国产一区二区成人久久免费影院| 97免费在线视频| 欧美风情第一页| 欧美黑人巨大videos精品| 欧美日韩亚洲不卡| 国产成人久久婷婷精品流白浆| 日本www在线观看| 91蜜桃在线观看| av电影成人| 这里只有精品国产| 99成人精品| 久久久97精品| 欧美黄色高清视频| 日本久久成人网| 日韩一二在线观看| 亚洲娇小娇小娇小| 性孕妇free特大另类| 亚洲柠檬福利资源导航| 手机在线观看国产精品| 好吊视频一区二区三区| 久久精品国产99国产精品| 日本免费久久高清视频| 日韩av女优在线观看| 久久久9色精品国产一区二区三区| 亚洲精品中文字幕av| www日本在线观看| 欧美日韩一区二区在线观看| 欧美一区视频在线| 欧美成人三级在线观看| 手机在线一区二区三区| 亚洲激情第一页| 亚洲精品在线网址| 免费一区二区三区四区| 在线欧美一区二区| 久久久久狠狠高潮亚洲精品| 色资源二区在线视频| 亚洲高清免费一级二级三级| 99久热在线精品视频| 日本精品在线| 最新中文字幕一区二区三区| 在线观看精品视频| 久操视频在线免费播放| 亚洲丝袜制服诱惑| 日日噜噜夜夜狠狠久久丁香五月 | 色综合一区二区日本韩国亚洲| 日韩欧美大尺度| 日本在线观看a| 欧美电影网站| 日本黄色一区二区| 九九热在线免费| 国产一区二区色噜噜| 欧美日韩一区成人| 97人人爽人人| 无码国模国产在线观看| 欧美成人一区二区三区片免费 | 亚洲 小说区 图片区| 日韩电影在线观看网站| 国产视频观看一区| 国产偷拍一区二区| 成人激情动漫在线观看| 国产在线精品一区| 九九在线视频| 国产精品久久久一本精品| 亚洲日本欧美在线| 丝袜中文在线| 亚洲国产精品影院| 久久久久久久久久久福利| 欧洲一区二区三区精品| 欧美探花视频资源| 欧美熟妇精品一区二区| 人体久久天天| 在线视频亚洲欧美| 免费三片在线播放| 国产农村妇女精品一二区| 国产精品久久久久不卡| 99久久久国产精品无码网爆| 成人一道本在线| 欧美一区二区三区四区在线观看地址 | 国产乱国产乱老熟300| 一本一本久久| 国产精品入口免费视频一| 国产黄色片网站| 久久久三级国产网站| 亚洲一区二区三区色| 欧美人与性动交α欧美精品图片| 婷婷久久综合九色综合伊人色| 国产精品69页| 亚洲网一区二区三区| 亚洲人成电影在线| 国产精品三区在线观看| 美女诱惑黄网站一区| 国产色综合天天综合网| 日韩黄色影片| 亚洲欧美日韩精品久久久久| 男人揉女人奶房视频60分| 高清欧美日韩| 日韩精品视频在线观看网址| 成人免费毛片xxx| 免费一级欧美片在线播放| 成人免费视频在线观看超级碰| 污污视频在线观看网站| 亚洲激情欧美激情| 亚洲国产精品毛片av不卡在线| eeuss鲁片一区二区三区| 中文字幕欧美亚洲| 青青草av在线播放| 国产精品综合网| 亚洲精品9999| 综合日韩av| 精品电影一区二区三区| 成人免费视频国产免费观看| 免费高清在线一区| 玛丽玛丽电影原版免费观看1977| 污污的网站在线免费观看| 欧美日韩一区在线观看| 97伦伦午夜电影理伦片| 欧美视频亚洲视频| 亚洲一区精品电影| 日本高清视频在线播放| 欧美性感一区二区三区| 爱爱免费小视频| 99热精品在线| 日韩精品dvd| 中文字幕日韩av电影| 日韩成人免费观看| 成人午夜电影久久影院| 国产精品一二三在线观看| 4438五月综合| xxxx欧美18另类的高清| 一本到在线视频| 中文成人av在线| 91人人澡人人爽人人精品| 国产欧美日韩精品一区二区三区 | 高清国产一区二区三区| 9色视频在线观看| 中文一区二区三区四区| 欧美大片网站在线观看| 亚洲av综合色区无码一区爱av| 国产精品传媒入口麻豆| 五月天视频在线观看| 99久久精品国产亚洲精品| 成人av资源在线播放| 麻豆视频在线观看免费| 在线不卡中文字幕播放| 91 在线视频| 国产精品1区2区3区在线观看| 日韩中文字幕亚洲精品欧美| 色播一区二区| 韩国日本不卡在线| 欧美zozo| 欧美日韩日日摸| 老司机成人免费视频| 国产91在线观看丝袜| 国产精品www在线观看| 麻豆成人入口| 国产精品99久久久久久久久| 亚洲成人三级| 精品人在线二区三区| 中日韩黄色大片| 国产欧美日韩卡一| 亚洲制服中文字幕| 亚洲视频碰碰| 日韩.欧美.亚洲| 欧美高清一级片| 91精品国产高清久久久久久91| 日本福利在线观看| 欧美日韩国产影片| 精品无码一区二区三区电影桃花| 99久久伊人精品| 欧美男女交配视频| 亚洲天堂偷拍| 欧美在线播放一区| 日本成人手机在线| 国产成人啪精品视频免费网| 九色porny在线| 精品亚洲一区二区三区| 国产精品美女一区| 欧美视频不卡中文| 中文字幕电影av| 久久久美女毛片| 欧美精品色视频| 久久视频一区| 国产成人一区二区三区别| 久草成人资源| 国产精品一区二区a| jizz亚洲女人高潮大叫| 国内精品在线一区| 欧美日韩视频在线播放| 亚洲精品久久久一区二区三区| 伊人久久国产精品| 欧美日韩久久久久| 青青草在线观看视频| 久久精品人人爽人人爽| 国产chinese中国hdxxxx| 美女脱光内衣内裤视频久久网站 | 亚洲欧美日韩不卡| 亚洲免费福利一区| 国产成人成网站在线播放青青 | 久久综合网络一区二区| 欧美交换配乱吟粗大25p| 欧美日韩色图| 久久国产精品亚洲va麻豆| 成人日韩视频| 国产精品美女久久久免费| 超碰99在线| 欧美老女人xx| 欧美jizzhd69巨大| 原创国产精品91| 飘雪影院手机免费高清版在线观看| 欧美一二三区在线观看| 中文在线字幕av| 日本道色综合久久| 黄色片免费观看视频| 亚洲国产va精品久久久不卡综合| 久久人妻无码aⅴ毛片a片app | 天天综合狠狠精品| 欧美日韩导航| 国产欧美韩日| 风间由美一区二区av101 | 自拍自偷一区二区三区| 国产日韩欧美一区二区三区四区| 五月亚洲婷婷| αv一区二区三区| 久久久久久亚洲精品美女| 国产日产亚洲精品| 国精品产品一区| 国产精品久久久久久影视| 国产精品粉嫩| 国产mv久久久| 成人国产精品一区二区免费麻豆 | 浮妇高潮喷白浆视频| 在线日韩欧美| 我的公把我弄高潮了视频| 亚洲国产裸拍裸体视频在线观看乱了中文 | 国产精品v欧美精品v日韩精品| 国产亚洲亚洲国产一二区| 91丝袜美腿美女视频网站| www.欧美| 国产福利不卡| 奇米影视777在线欧美电影观看| 国产免费一区| 在线一级成人| 亚洲精品9999| 欧美精品网站| 青青草精品视频在线| 销魂美女一区二区三区视频在线| 99精品免费在线观看| 日韩二区三区在线观看| 中文字幕22页| 国产91精品入口| 中文字幕一区三区久久女搜查官| 99精品欧美一区二区三区综合在线| 亚洲图片综合网| 久久久久久久久久久久久女国产乱 | 国产99亚洲| 亚洲免费不卡| 欧美粗暴jizz性欧美20| 成年人网站免费视频| 可以看av的网站久久看| 中文字幕66页| 成人精品亚洲人成在线| aa一级黄色片| 中文字幕一区二区三区在线不卡| 青青草国产在线观看| 欧美日韩在线影院| 亚洲一级片免费看| 欧美成人国产一区二区| 久草视频视频在线播放| 日韩一区二区福利| tube8在线hd| 国产精品久久久久久av| 88久久精品| 日韩精品不卡| 欧美日韩 国产精品| 成人久久久久久久久| 极品少妇一区二区| www.自拍偷拍| 亚洲免费av网站| 日本视频在线观看免费| 日韩一区和二区| 国产尤物视频在线| 欧美日本亚洲视频| 电影一区二区| 国产亚洲一区二区三区在线播放| 欧美一区二区三| 国产美女主播在线播放| 极品少妇一区二区三区精品视频| 中文字幕一区二区人妻在线不卡| 中文字幕综合网| 国产一区二区视频免费| 日韩无一区二区| 成人综合影院| 91黄色8090| 亚洲码欧美码一区二区三区| 亚洲欧美成人一区| 国产精品久久久久久久久久妞妞 | 欧美sss在线视频| 欧美爱爱视频网站| 首页综合国产亚洲丝袜| 亚洲一二三四五| 亚洲人午夜精品天堂一二香蕉| 精产国品一区二区| 亚洲福利在线播放| caoporn免费在线视频| 国产精品久久久久不卡| 久久爱www成人| 国产中文字幕在线免费观看| 国产精品性做久久久久久| 国产三级在线观看完整版| 黑人巨大精品欧美一区二区免费| 性一交一乱一乱一视频| 久久精品这里热有精品| 欧美黄色网络| 水蜜桃一区二区| 日产欧产美韩系列久久99| 亚洲第一页av| 黑人精品xxx一区| 欧美视频xxx| 久久久久国产视频| 亚洲2区在线| 久艹在线免费观看| 东方aⅴ免费观看久久av| 中文字幕在线有码| 日韩久久久精品| 污污在线观看| 国产精品区二区三区日本| 亚洲午夜伦理| yjizz视频| 狠狠久久五月精品中文字幕| 手机看片一区二区三区| 97超碰国产精品女人人人爽 | 久久香蕉视频网站| 粉嫩久久99精品久久久久久夜| 青娱乐av在线| 精品99999| 人在线成免费视频| 久中文字幕一区| 日韩电影在线看| 手机免费观看av| 欧美精品高清视频| 成视频免费观看在线看| 亚洲一区二区三区视频| 亚洲性感美女99在线| 性色av蜜臀av浪潮av老女人 | 久久久久久亚洲精品| 老司机精品视频在线播放| 六月丁香激情网| 国产日韩高清在线| 国产一区二区波多野结衣| 久久av资源网站| 久久99国产精品久久99大师| 成人毛片视频网站| 久久精品夜夜夜夜久久| 一级黄色片在线| 精品中文字幕在线| 欧美理伦片在线播放| 日韩精品一区二区三区不卡| 国产精品久久久久婷婷二区次| 国产乱叫456在线| 孩xxxx性bbbb欧美| 国产免费久久| 亚洲欧美日韩中文字幕在线观看| 亚洲成a人片在线观看中文| 少妇性bbb搡bbb爽爽爽欧美| 国产精品高精视频免费| 欧美激情五月| 好吊视频在线观看| 91精品国产综合久久久蜜臀图片| 国产www视频在线观看| 日本10禁啪啪无遮挡免费一区二区| 久久99国产精品久久99果冻传媒| 久久香蕉精品视频| 这里只有精品在线观看| 波多野结衣一区二区三区免费视频| 欧美性久久久久| 综合久久国产九一剧情麻豆| 三级视频在线看| 91精品国产综合久久久久久蜜臀 | 91制片厂毛片| 午夜影院在线观看欧美| 自拍视频在线免费观看| 国内精品视频在线播放| 国产在线不卡一卡二卡三卡四卡| 日韩黄色在线视频| 久久精品国产成人| 亚洲精品无吗| 95视频在线观看| 91麻豆精品国产自产在线观看一区| 91超碰国产在线| 男女h黄动漫啪啪无遮挡软件| xfplay精品久久| 国产77777|