亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

黑馬程序員——【Java高新技術】——代理

2019-11-14 21:18:40
字體:
來源:轉載
供稿:網友
黑馬程序員——【java高新技術】——代理

---------- android培訓、java培訓、期待與您交流! ----------

一、“代理概述”及“AOP概念”

 ?。ㄒ唬┐砀攀?/strong>

  1、問題:要為已存在的多個具有相同接口的目標類的各個方法增加一些系統功能,例如,異常處理、日志、計算方法的運行時間、事務管理等等,如何去做?

  解答:編寫一個與目標類具有相同接口的代理類,代理類的每個方法調用目標類的相同方法,并在調用方法時加上系統功能的代碼。

  2、代理原理圖,如下:

  

  3、代理的優點

  如果采用工廠模式和配置文件的方式進行管理,則不需要修改客戶端程序,在配置文件中配置是使用目標類、還是代理類,這樣以后很容易切換。例如,想要日志功能時就配置代理類,否則配置目標類,這樣,增加系統功能很容易,以后運行一段時間后,又想去掉系統功能也很容易。

 ?。ǘ〢OP概念

  1、問題引入:

 ?。?)系統中存在交叉業務,一個交叉業務就是要切入到系統中的一個方面,如下所示:

             安全 事務 日志

  StudentService ———|——————|——————|—————

  CourseService ———|——————|——————|—————

  MiscService ———|——————|——————|—————

  (2)用具體的程序代碼描述交叉業務:

  method1 method2 method3

  { { {

  ------------------------------------------切面

  .... .... ......

  ------------------------------------------切面

  } } }

  2、AOP概念

 ?。?)定義:交叉業務的編程問題即為面向方面的編程(aspect oriented PRogram ,簡稱AOP),AOP的目標就是要使交叉業務模塊化。

  (2)可以采用將切面代碼移動到原始方法的周圍,這與直接在方法中編寫切面代碼的運行效果是一樣的,如下所示:

  ----------------------------------------切面

  func1 func2 func3

  { { {

  .... .... ....

  } } }

  -----------------------------------------切面

  總結:(1)使用代理技術正好可以解決這種交叉業務模塊化的問題,代理是實現AOP功能的核心和關鍵技術。(2)安全,事務,日志等功能要貫穿到好多個模塊中,所以,它們就是交叉業務。

二、動態代理技術

  1、手動增加代理類存在的問題?

  要為系統中的各種接口的類增加代理功能,則需要太多的代理類,全部采用靜態代理方式,就要寫成百上千個代理類,將是一件工作量巨大且非常麻煩的事情。

  2、如何解決上述存在的問題?

  JVM可以在“運行期”動態生成出類的字節碼,這種動態生成的類往往被用作代理類,即動態代理類。

  3、動態類需注意細節:

  JVM生成的動態類必須實現一個或多個接口,這樣JVM就知道該實現什么方法。所以,JVM生成的動態類只能用作具有相同接口的目標類的代理。

  4、如果一個目標類自身沒有實現接口,如何讓JVM動態生成的代理類與目標類有相同的方法列表呢?

  生成的代理類的方法聲明要不要和目標類的方法一樣?要。但目標類自身并沒有實現接口,那通過什么樣的方式告訴JVM生成的代理類與目標類有相同的方法列表,JVM干不了這件事情,因為沒接口。

  這時候有一個第三方CGLIB庫,CGLIB庫可以動態生成一個類的子類,一個類的子類也可以用作該類的代理,所以,如果要為一個沒有實現接口的類生成動態代理類,那么可以使用CGLIB庫。

  5、在代理方法中什么位置可以插入系統功能代碼?

  代理類的各個方法中通常除了要調用目標的相應方法和對外返回目標返回的結果外,還可以在代理方法中的如下四個位置加上系統功能代碼:

 ?。?)在調用目標方法之前

 ?。?)在調用目標方法之后

 ?。?)在調用目標方法前后

  (4)在處理目標方法異常的catch塊中

三、JVM動態生成的類

  (一)創建動態類及查看其方法列表信息

  1、要求:

 ?。?)創建實現了Collection接口的動態類和查看其名稱,分析Proxy.getProxyClass方法的各個參數。

 ?。?)編碼列出動態類中的所有構造方法和參數簽名

 ?。?)編碼列出動態類中的所有方法和參數簽名

  2、示例代碼:

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 import java.util.Collection; 5 public class ProxyTest { 6     /** 7      * @param args 8      * @throws SecurityException 9      * @throws NoSuchMethodException10      * @throws Exception11      * @throws IllegalArgumentException12      * @throws IllegalaccessException13      * @throws InstantiationException14      */15     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {16         Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);17         System.out.println(clazzProxy1.getName());18         19         System.out.println("------------begin constructor list ------------");20         Constructor[] constructors = clazzProxy1.getConstructors();21         for(Constructor constructor : constructors){22             String name = constructor.getName();23             StringBuilder sb = new StringBuilder(name);24             sb.append("(");25             Class[] clazzParams = constructor.getParameterTypes();26             for(Class clazzParam : clazzParams ){27                 sb.append(clazzParam.getName()).append(",");28             }29             if( clazzParams!=null && clazzParams.length!=0)30                 sb.deleteCharAt(sb.length()-1);31             sb.append(")");32             System.out.println(sb);33         }34         35         System.out.println("------------begin method list -------------");36         Method[] methods = clazzProxy1.getMethods();37         for(Method method : methods){38             String name = method.getName();39             StringBuilder sb = new StringBuilder(name);40             sb.append("(");41             Class[] clazzParams = method.getParameterTypes();42             for(Class clazzParam : clazzParams ){43                 sb.append(clazzParam.getName()).append(",");44             }45             if( clazzParams!=null && clazzParams.length!=0)46                 sb.deleteCharAt(sb.length()-1);47             sb.append(")");48             System.out.println(sb);49         }50     }51 }

 ?。ǘ﹦摻▌討B類的實例對象及調用其方法

  1、創建動態類的實例對象有三種方式:

 ?。?)首先通過Proxy類的getProxyClass(ClassLoader loader, Class<?>... interfaces)方法,獲取代理類的對象;然后通過反射獲得構造方法;最后通過接口InvocationHandler的子類創建對象;

  (2)首先通過Proxy類的getProxyClass(ClassLoader loader, Class<?>... interfaces)方法,獲取代理類的對象;通過反射獲得構造方法;通過給構造方法的newInstance()傳入InvocationHandler的匿名內部類來創建對象;

 ?。?)直接通過Proxy類的newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,創建對象。

  2、創建動態類的實例對象的代碼實現

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 public class ProxyTest { 8     /** 9      * @param args10      * @throws SecurityException11      * @throws NoSuchMethodException12      * @throws Exception13      * @throws IllegalArgumentException14      * @throws IllegalAccessException15      * @throws InstantiationException16      */17     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {18         Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);19         Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);20 21         System.out.println("------------begin create instance list --------------");22         //System.out.println("------------方式一:創建動態類的實例對象 ----------");23         class MyInvocationHandler1 implements InvocationHandler{24             @Override25             public Object invoke(Object proxy, Method method, Object[] args)26                     throws Throwable {27                 // TODO Auto-generated method stub28                 return null;29             }30         }31         Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler1());32         System.out.println(proxy1);33 34         // System.out.println("------------方式二:創建動態類的實例對象 -----------");35         Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){36             @Override37             public Object invoke(Object proxy, Method method, Object[] args)38                     throws Throwable {39                 // TODO Auto-generated method stub40                 return null;41             }42         });43 44         // System.out.println("------------方式三:創建動態類的實例對象 ------------");45         Collection proxy3 = (Collection)Proxy.newProxyInstance(46                 Collection.class.getClassLoader(),47                 new Class[]{Collection.class},48                 new InvocationHandler(){49                     ArrayList target = new ArrayList();50                     @Override51                     public Object invoke(Object proxy, Method method,52                             Object[] args) throws Throwable {53                         long beginTime = System.currentTimeMillis();54                         Object retVal = method.invoke(target, args);55                         long endTime = System.currentTimeMillis();56                         System.out.println(method.getName()+"run time"+(endTime-beginTime));57                         return retVal;58                     }59                 }60                 );61         proxy3.add("zxx");62         proxy3.add("flx");63         proxy3.add("lhm");64         proxy3.add("bxd");65         proxy3.add("yzz");        66         System.out.println(proxy3.size());67     }68 }

 ?。ㄈ┛偨Y思考

  問題:讓JVM創建動態類及其實例對象,需要給它提供哪些信息?

  解答:主要包括三個方面的信息:

  (1)生成的類中有哪些方法,通過讓其實現哪些接口的方式進行告知;

 ?。?)產生的類字節碼必須有個一個關聯的類加載器對象;

 ?。?)生成的類中的方法的代碼是怎樣的,也得由我們提供。把我們的代碼寫在一個約定好了接口對象的方法中,把對象傳給它,它調用我的方法,即相當于插入了我的代碼。提供執行代碼的對象就是那個InvocationHandler對象,它是在創建動態類的實例對象的構造方法時傳遞進去的。在上面的InvocationHandler對象的invoke方法中加一點代碼,就可以看到這些代碼被調用運行了。

  * 用Proxy.newInstance方法直接一步就創建出代理對象。

四、動態生成的類的內部代碼分析

  在上面“創建動態類的實例對象”的代碼中,動態生成的類實現了Collection接口(可以實現若干接口),生成的類有Collection接口中的所有方法和一個如下接受InvocationHandler參數的構造方法。

  1、問題:構造方法接受一個InvocationHandler對象,接收這個對象要干什么用呢?該方法內部的代碼是怎樣的呢?

 ?。?)構造方法接收一個參數,為了記住這個參數,以后運用它。

 ?。?)內部代碼:

1 $Proxy0 implements Collection{2     InvocationHandler handler;3     public $Proxy0(InvocationHandler handler){4         this.handler = handler;5     }6 }

  2、問題:實現Collection接口的動態類中的各個方法的代碼又是怎樣的呢? InvocationHandler接口中定義的invoke方法接收的三個參數又是什么意思?

 1 (1)$Proxy0 implements Collection{ 2     InvocationHandler handler; 3     public $Proxy0(InvocationHandler handler){ 4         this.handler = handler; 5     } 6     //生成的Collection接口中的方法的運行原理 7     int size(){ 8         return handler.invoke(this, this.getClass().getMethod("size"), null); 9     }10     void clear(){11         handler.invoke(this, this.getClass().getMethod("clear"), null);12     }13     boolean add(Object obj){14         handler.invoke(this, this.getClass().getMethod("add"), obj);15     }16 }

 ?。?)InvocationHandler接口中定義的invoke方法接收的三個參數意義,如下圖說明:

  

  說明:客戶端調用了代理對象objProxy,調用了代理對象的add()方法,為該方法傳遞了字符串參數"abc"。

  3、為什么動態類的實例對象的getClass()方法返回了正確結果呢?

  調用調用代理對象的從Object類繼承的hashCode, equals, 或toString這幾個方法時,代理對象將調用請求轉發給InvocationHandler對象,對于其他方法,則不轉發調用請求。

五、動態生成的類成為目標類的代理

  1、動態代理的工作原理圖

  

  2、eclipse重構出一個getProxy方法綁定接收目標同時返回代理對象,怎樣將目標類作為參數傳進去?

 ?。?)直接在InvocationHandler實現類中創建目標類的實例對象,可以看運行效果和加入日志代碼,但沒有實際意義。

 ?。?)為InvocationHandler實現類注入目標類的實例對象,不能采用匿名內部類的形式了。

 ?。?)讓匿名的InvocationHandler實現類訪問外面方法中的目標類實例對象的final類型的引用變量。

  3、在上面將目標類作為參數傳入之后,將系統功能代碼模塊化,即將切面代碼也改為通過參數形式提供,怎樣把要執行的系統功能代碼以參數形式提供?

  (1)把要執行的代碼裝到一個對象的某個方法里,然后把這個對象作為參數傳遞,接收者只要調用這個對象的方法,即等于執行了外界提供的代碼!

 ?。?)為bind方法增加一個Advice參數。

  4、將目標類和系統功能作為參數傳遞給getProxy()方法,實現示例代碼如下:

 ?。?)創建ProxyTest類

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 public class ProxyTest { 8     /** @param args 9      * @throws SecurityException10      * @throws NoSuchMethodException11      * @throws Exception 12      * @throws IllegalArgumentException13      * @throws IllegalAccessException14      * @throws InstantiationException15      */16     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {17         final ArrayList target = new ArrayList();//將目標抽取出來,方法里面的內部類要訪問局部變量必須添加final關鍵字        18         Collection proxy3 = (Collection)getProxy(target,new MyAdvice());//抽取出來的方法19         proxy3.add("zxx");20         proxy3.add("flx");21         proxy3.add("lhm");        22         System.out.println(proxy3.size());23     }24     private static Object getProxy(final Object target,final Advice advice) { /*做成通用的方法,返回Object*/25         Object proxy3 = Proxy.newProxyInstance(26                 /*Collection.class.getClassLoader(),        //第一個參數*/27                 target.getClass().getClassLoader(),            //    代理類的類加載器與目標類的類加載器相同,與目標類有關。28                 29                 /*new Class[]{Collection.class},        //第二個參數*/30                 target.getClass().getInterfaces(),    //與target實現相同的接口,代理類要實現的接口也是目標類實現的接口,與目標類有關31                 32                 new InvocationHandler(){        //第三個參數,33                     @Override34                     public Object invoke(Object proxy, Method method,35                             Object[] args) throws Throwable {36                         /*37                         long beginTime = System.currentTimeMillis();    //將系統功能抽取為一個對象38                         Object retVal = method.invoke(target, args);39                         long endTime = System.currentTimeMillis();    //將系統功能抽取為一個對象                        40                         System.out.println(method.getName()+"run time"+(endTime-beginTime));41                         return retVal;42                         */43                         advice.beforeMethod(method);44                         Object retVal = method.invoke(target, args);45                         advice.afterMethod(method);    46                         return retVal;47                     }48                 }49                 );50         return proxy3;51     }52 }

 ?。?創建Advice接口

import java.lang.reflect.Method;public interface Advice {    //一般來說,這個建議的接口應該有四個方法,這四個方法可以分別插入:    /* 代理類的各個方法中通常除了要調用目標的相應方法和對外返回目標返回的結果外,     * 還可以在代理方法中的如下四個位置加上系統功能代碼:     *    1.在調用目標方法之前     *    2.在調用目標方法之后     *    3.在調用目標方法前后     *    4.在處理目標方法異常的catch塊中      * */    void beforeMethod(Method method);    void afterMethod(Method method);    }

 ?。?)創建Advice接口的子類MyAdvice

 1 import java.lang.reflect.Method; 2 public class MyAdvice implements Advice { 3     long beginTime = 0; 4     public void beforeMethod(Method method) { 5         // TODO Auto-generated method stub 6         System.out.println("到黑馬程序員訓練營來學習了!"); 7         beginTime = System.currentTimeMillis();    //將系統功能抽取為一個對象 8     } 9 10     public void afterMethod(Method method) {11         // TODO Auto-generated method stub12         System.out.println("從黑馬程序員訓練營畢業工作了!");13         long endTime = System.currentTimeMillis();    //將系統功能抽取為一個對象    14         System.out.println(method.getName()+" method run of time "+(endTime-beginTime));15         System.out.print(System.lineSeparator() );16     }17 }

六、實現類似spring的可配置的AOP框架

  (一)工廠類BeanFactory

   1、工廠類BeanFactory:負責創建目標類或代理類的實例對象,并通過配置文件實現切換。

   2、getBean方法:根據參數字符串返回一個相應的實例對象。如果參數字符串在配置文件中對應的類名不是ProxyFactoryBean,則直接返回該類的實例對象,否則返回該類示例對象的getProxy方法返回的對象。

   3、BeanFactory的構造方法:接收代表配置文件的輸入流對象的配置文件。

   4、ProxyFactoryBean為BeanFactory提供配置參數信息:(1)目標(target)(2)通告(advice)

   5、BeanFactory和ProxyFactoryBean:

   (1)BeanFactory是一個純粹的bean工程,就是創建bean即相應的對象的工廠。

  ?。?)ProxyfactoryBean是BeanFactory中的一個特殊的Bean,是創建代理的工廠。

 ?。ǘ崿F類似spring的可配置的AOP框架的思路:

   1、創建BeanFactory類:

  ?。?)構造方法:接受一個配置文件,通過Properties對象加載InputStream流對象。

  ?。?)創建getBean(String name)方法:根據類名name,拿到對應的類名className。

   (3)根據類名獲取其字節碼對象,并創建實例對象bean。

  ?。?)判斷bean是否是特殊的Bean即ProxyFactoryBean。

   ?、?如果是,就要創建代理類,并設置目標(target)和通告(advice),分別得到各自的實例對象,并返回代理類實例對象。

   ?、?如果不是在返回Bean對象自己。

   2、創建ProxyFactoryBean類,定義target和advice;定義getProxy()方法,用于創建代理類對象。

   3、創建配置文件config.properties,對配置文件進行配置,配置內容如下

    xxx=java.util.ArrayList

    #xxx=cn.itheima.day3.aopframework.ProxyFactoryBean

    xxx.advice=cn.itheima.day3.MyAdvice

    xxx.target=java.util.ArrayList

    注: #表示注釋當前行。

   4、作一個測試類:AopFrameworkTest進行測試。

 ?。ㄈ┩暾a示例

   1、創建BeanFactory類:

package cn.itheima.day3.aopframework;import java.io.IOException;import java.io.InputStream;import java.util.Properties;import cn.itheima.day3.Advice;public class BeanFactory {    Properties props = new Properties();    public BeanFactory(InputStream ips){        try {            props.load(ips);        } catch (IOException e) {            e.printStackTrace();        }    }    public Object getBean(String name){        String className = props.getProperty(name);//根據類名name,拿到對應的類名。        Object bean = null;        try {            Class clazz = Class.forName(className);            bean = clazz.newInstance();        } catch (Exception e) {            e.printStackTrace();        }        if(bean instanceof ProxyFactoryBean){            Object proxy = null;            ProxyFactoryBean ProxyFactoryBean = (ProxyFactoryBean)bean;            try {                Advice advice = (Advice)Class.forName(props.getProperty(name+".advice")).newInstance();                Object target = Class.forName(props.getProperty(name+".target")).newInstance();                ProxyFactoryBean.setAdvice(advice);                ProxyFactoryBean.setTarget(target);                proxy = ProxyFactoryBean.getProxy();            } catch (Exception e) {                e.printStackTrace();            }            return proxy;        }        return bean;    }}

  

  2、創建ProxyFactoryBean類:

 1 package cn.itheima.day3.aopframework; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 import cn.itheima.day3.Advice; 7 public class ProxyFactoryBean { 8     private Advice advice; 9     private Object target;10     public Advice getAdvice() {11         return advice;12     }13     public void setAdvice(Advice advice) {14         this.advice = advice;15     }16     public Object getTarget() {17         return target;18     }19     public void setTarget(Object target) {20         this.target = target;21     }22     public Object getProxy() {23         Object proxy3 = Proxy.newProxyInstance(                24                 target.getClass().getClassLoader(),    //    代理類的類加載器與目標類的類加載器相同,與目標類有關。25                 target.getClass().getInterfaces(),        //與target實現相同的接口,代理類要實現的接口也是目標類實現的接口,與目標類有關26                 27                 new InvocationHandler(){    //第三個參數28                     @Override29                     public Object invoke(Object proxy, Method method,30                             Object[] args) throws Throwable {31                         advice.beforeMethod(method);32                         Object retVal = method.invoke(target, args);33                         advice.afterMethod(method);34                         return retVal;35                     }36                 }37                 );38         return proxy3;39     }40 }

  3、創建配置文件config.properties。

xxx=java.util.ArrayList#xxx=cn.itheima.day3.aopframework.ProxyFactoryBeanxxx.advice=cn.itheima.day3.MyAdvicexxx.target=java.util.ArrayList

  4、創建AopFrameworkTest測試類,進行測試:

 1 package cn.itheima.day3.aopframework; 2  3 import java.io.InputStream; 4 public class AopFrameworkTest { 5     /** 6      * @param args 7      */ 8     public static void main(String[] args) { 9         // TODO Auto-generated method stub10         InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");11         Object bean = new BeanFactory(ips).getBean("xxx");12         System.out.println(bean.getClass().getName());13     }14 }

  5、設計到的接口Advice及其子類MyAdvice

 ?。?)Advice接口:

1 package cn.itheima.day3;2 import java.lang.reflect.Method;3 public interface Advice {    4     void beforeMethod(Method method);5     void afterMethod(Method method);6 }

 ?。?)MyAdvice類:

 1 package cn.itheima.day3; 2 import java.lang.reflect.Method; 3 public class MyAdvice implements Advice { 4     long beginTime = 0; 5     public void beforeMethod(Method method) { 6         // TODO Auto-generated method stub 7         System.out.println("到黑馬程序員訓練營來學習了!"); 8         beginTime = System.currentTimeMillis();    //將系統功能抽取為一個對象 9     }10 11     public void afterMethod(Method method) {12         // TODO Auto-generated method stub13         System.out.println("從黑馬程序員訓練營畢業工作了!");14         long endTime = System.currentTimeMillis();    //將系統功能抽取為一個對象    15         System.out.println(method.getName()+" method run of time "+(endTime-beginTime));16         System.out.print(System.lineSeparator() );17     }18 }

---------- android培訓、java培訓、期待與您交流! ----------


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品videofree1080p| 日韩免费av一区二区| 中文字幕欧美视频在线| 91精品视频免费观看| 国产欧美在线观看| 国产精品久久久久久久app| 亚洲精品电影久久久| 久久精品色欧美aⅴ一区二区| 国产精品毛片a∨一区二区三区|国| 亚洲国产精品久久久久秋霞不卡| 欧美野外猛男的大粗鳮| 欧美日韩在线一区| 欧美精品videossex性护士| 亚洲第一区中文99精品| 一本色道久久综合亚洲精品小说| 88xx成人精品| 日韩av综合网站| 亚洲激情免费观看| 欧美限制级电影在线观看| 欧美性xxxx极品hd满灌| 久久精品成人欧美大片| 久久色在线播放| 国产免费亚洲高清| 456亚洲影院| 91超碰caoporn97人人| 亚洲国产精品久久久久久| 国产98色在线| 在线播放精品一区二区三区| 91高清免费在线观看| 97国产真实伦对白精彩视频8| 国产欧美日韩中文字幕在线| 91天堂在线视频| 亚洲精美色品网站| 日韩性生活视频| 精品久久在线播放| 国产精品video| 欧美激情va永久在线播放| 日本一区二区不卡| 91青草视频久久| 91大神在线播放精品| 国产日韩欧美自拍| 亚洲免费av电影| 色婷婷av一区二区三区在线观看| 欧美在线激情网| 992tv成人免费视频| 欧美黑人xxxx| 欧美视频专区一二在线观看| 久久久久久久久久久久久久久久久久av| 精品国产91久久久久久| 91中文在线视频| 日韩成人黄色av| 日韩不卡在线观看| 夜夜嗨av一区二区三区免费区| 国产在线视频91| 国产亚洲成精品久久| 欧美性受xxxx黑人猛交| 在线播放国产精品| 日韩最新在线视频| 欧美丰满老妇厨房牲生活| 久久成人一区二区| 久久久久女教师免费一区| 色综合色综合网色综合| 欧洲s码亚洲m码精品一区| 欧美一级高清免费| 91久久精品国产91久久性色| 亚洲黄色在线观看| 96pao国产成视频永久免费| 国产精品一区二区久久精品| 国产精品自拍视频| 日韩av影片在线观看| 青青草成人在线| 欧美伦理91i| 这里只有精品在线播放| 91丨九色丨国产在线| 日本午夜精品理论片a级appf发布| 日韩中文字幕国产| 在线看片第一页欧美| 欧美性xxxxx| 国产精品久久久久免费a∨大胸| 欧美精品www在线观看| 在线播放日韩精品| 色偷偷偷亚洲综合网另类| 91沈先生在线观看| 欧美日韩xxx| 国产日本欧美一区二区三区| 国产精品专区h在线观看| 97在线视频免费播放| 97不卡在线视频| 亚洲欧美日韩国产精品| 久久久国产精品亚洲一区| 日韩电影免费在线观看| 91精品久久久久| 国产丝袜一区二区三区免费视频| 国产剧情久久久久久| 午夜精品视频在线| 久久五月天色综合| 亚洲国产精品人人爽夜夜爽| www.色综合| 亚洲国内精品在线| 日韩av片免费在线观看| 国产精品丝袜一区二区三区| 欧美日韩亚洲精品内裤| 亚洲天堂av女优| 欧美日韩加勒比精品一区| 中文字幕国产日韩| 日韩在线欧美在线| 久久综合电影一区| 欧美激情在线观看视频| 欧美人在线视频| 精品日本美女福利在线观看| 亚洲精品成人网| 久久久国产精品x99av| 国产精彩精品视频| 福利一区视频在线观看| 亚洲国产精品久久| 国产精品久久网| 日韩电影中文字幕在线| 国产精品久久久| 日韩电影在线观看免费| 欧美成人全部免费| 久久久成人av| 日韩欧美中文第一页| 日本中文字幕成人| 国产精品va在线播放| 亚洲2020天天堂在线观看| 久久天天躁狠狠躁夜夜躁| 亚洲精品国产成人| 中文字幕一区二区精品| 超碰日本道色综合久久综合| 成人国产精品色哟哟| 国产精品99久久久久久久久| 91国产中文字幕| 精品国产鲁一鲁一区二区张丽| 欧美性资源免费| 国产精品精品国产| 国产精品美女视频网站| 亚洲视频在线免费观看| 一区二区成人精品| 97视频免费看| 国产mv久久久| 亚洲日韩欧美视频一区| 97免费视频在线播放| 国产在线精品成人一区二区三区| 中文字幕亚洲一区二区三区五十路| 91po在线观看91精品国产性色| 中文字幕一精品亚洲无线一区| 欧美国产日韩视频| 成人免费视频xnxx.com| 黄色成人av在线| 中文日韩电影网站| 亚洲影院色无极综合| 日韩国产欧美精品在线| 日韩精品亚洲精品| 国产精品美女在线观看| 欧美丰满老妇厨房牲生活| 久久久久久久久久久久久久久久久久av| 亚洲人成在线电影| 亚洲国产精品va在线看黑人动漫| 欧美亚洲成人网| 美女av一区二区三区| 日韩电影在线观看免费| 欧美日韩在线视频首页| 成人网在线免费观看| 成人a在线观看|