日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

史上最烂 spring aop 原理分析

發布時間:2024/3/13 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 史上最烂 spring aop 原理分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

盜引·中篇·spring aop

spring aop: jdk 動態代理和 cglib 動態代理的特點、區別、使用方式、原理及各自對反射的優化、二者在 spring 中的統一、通知順序、從 @Aspect 到 Advisior、靜態通知調用、動態通知調用。


版本

  • jdk:8
  • spring:5.3.20
  • spring boot:2.7.0

1 spring aop

1.1 aop

??AOP (Aspect Oriented Programming) 即面向切面編程,其同 OOP (Object Oriented Programming) 即面向對象編程一樣,是一種編程思想,其含義為通過預編譯方式和運行期間動態代理實現程序功能的統一維護。AOP 是 OOP 的延續,是對 OOP 的一種補充。

??aop 采取了橫向抽取機制,取代了傳統的縱向繼承機制,其可攔截指定的方法并對其功能性增強,且其是非侵入式,分離了業務代碼與非業務代碼。常見的 aop 應用場景有日志記錄、事務管理、權限認證、性能統計、異常處理等。

??aop 是一種編程思想,其典型的實現有 spring aop 和 AspectJ。二者最大的區別是 spring aop 使用動態代理,AspectJ 使用靜態代理。

??spring 中 aop 是基于動態代理實現的,即基于 jdk 動態代理和 cglib 動態代理。但其也整合了 AspectJ。spring 自己實現的 aop 可以通過 xml、接口實現來使用,但不支持注解,所以 spring aop 引入了 AspectJ。實際上 spring aop 只是整合了 AspectJ 中的注解使用方式,最終會將 AspectJ 注解相關解析成 spring aop 自己的實現,當然底層依然是基于動態代理。

1.2 spring aop

1.2.1 八大核心概念
  • Joinpoint(連接點):即類中可以被增強的方法,統稱為連接點。包括抽象方法、普通方法等。
  • Pointcut(切入點):又稱切點,即需要被攔截的連接點,或者理解為需要被增強的方法。連接點中包含了切入點。
  • **Advice(通知) **:即增強,即為需要被增強的方法添加的增強內容。
  • Aspect(切面):切面 = 切點 + 通知。
  • Introduction(引介):即一種特殊的通知,即在運行期間動態的擴展類。即在運行期間為類添加一些屬性和方法。
  • Target(目標):即要被增強的方法所在的類。其實例被稱為目標對象。
  • Weaving(織入):即將通知(增強內容)按照切入點添加到目標中的過程。
  • Proxy(代理):即目標類被織入通知后產生的類,其實例被稱為代理對象。
1.2.2 五種通知方式
  • before(前置通知):即通知內容在目標方法執行前執行。
  • after-returing(返回后通知):即通知內容在目標方法返回后執行。
  • after-throwing(拋出異常后通知):即通知內容在目標方法拋出異常后執行。
  • after(后置通知):即通知內容在目標方法執行后執行。
  • around(環繞通知):即通知內容在目標方法執行前后執行。
1.2.3 三種織入時期
  • 編譯期:即在類編譯期將通知內容織入到目標類中,AspectJ 就采用這種方式。實際上 AspectJ 的織入可細分為兩種方式,即編譯期織入和后編譯期織入,二者的區別是:編譯期織入是將通知內容在 .java 文件編譯時直接織入到其 .class 字節碼文件中;后編譯期織入是將已經織入通知內容的 .class 字節碼文件或整個 jar 包織入。
  • 類加載期:即在 jvm 加載類時將通知內容織入到目標類中,AspectJ 也可使用這種方式。
  • 運行期:即在程序運行期將通知內容織入到目標類中(實際上是生成了一份新的字節碼文件),動態代理就采用這種方式。

2 設計實現

??切面 = 切點 + 通知。spring aop 設計實現中,切面、切點、通知接口分別為 Advisor、Pointcut、Advice。其中針對五種不同的通知方式又擴展了五個通知接口,分別是 MethodBeforeAdvice(前置通知接口)、AfterReturningAdvice(返回后通知接口)、ThrowsAdvice(拋出異常后通知接口)、AfterAdvice(后置通知接口)、MethodInterceptor(環繞通知接口)。同時,為了集成 AspectJ aop 實現中的注解功能,又為 AspectJ 中切點、通知相關的注解提供了默認的實現了。 spring aop 的相關類圖如下:

  • Advisor:即切面接口,切面 = 切點 + 通知。Advisor 通過字接口 PointcutAdvisor 間接持有了一個 Pointcut(切點),又直接持有了一個 Advice(通知)。spring aop 中的所有不同通知方式的 aop 最后都會轉換為一個 Advisor 即切面去執行。
  • Pointcut:即切點接口。
  • ExpressionPointcut:即 SpEL 切點接口。
  • Advice:即通知接口。
  • MethodBeforeAdvice:即前置通知接口。
  • AfterReturningAdvice:即返回后置通知接口。
  • ThrowsAdvice:即拋出異常后通知接口。
  • AfterAdvice:即后置通知接口(finally 快執行完后)。
  • MethodInterceptor:即環繞通知接口。非環繞通知最終都會轉化為環繞通知執行。
  • AspectJExpressionPointcut:即為集成 AspectJ 的 @Pointcut 注解功能而提供的表達式切點實現類。亦可理解為由 @Pointcut 注解聲明的切點最終會被解析為 AspectJExpressionPointcut 的實例。
  • AspectJMethodBeforeAdvice:即為集成 AspectJ 的 @Before 注解功能而提供的前置通知實現類。亦可理解為由 @Before 注解聲明的通知最終都會被解析為 AspectJMethodBeforeAdvice 的實例。非環繞通知。
  • AspectJAfterReturningAdvice:即為集成 AspectJ 的 @AfterReturning 注解功能而提供的返回后通知實現類。亦可理解為由 @AfterReturning 注解聲明的通知最終都會被解析為 AspectJAfterReturningAdvice 的實例。非環繞通知。
  • AspectJAfterAdvice:即為集成 AspectJ 的 @After 注解功能而提供的后置通知實現類。亦可理解為由 @After 注解聲明的通知最終都會被解析為 AspectJAfterAdvice 的實例。實現了 MethodInterceptor 接口,所以其本質為環繞通知。
  • AspectJThrowingAdvice:即為集成 AspectJ 的 @AfterThrowing 注解功能而提供的拋出異常后通知實現類。亦可理解為由 @AfterThrowing 注解聲明的通知最終都會被解析為 AspectJThrowingAdvice 的實例。實現了 MethodInterceptor 接口,所以其本質為環繞通知。
  • AspectJAroundAdvice:即為集成 AspectJ 的 @Around 注解功能而提供的環繞通知實現類。亦可理解為由 @Around 注解聲明的通知最終都會被解析為 AspectJAroundAdvice 的實例。實現了 MethodInterceptor 接口,所以其本質為環繞通知。
  • MethodBeforeAdviceInterceptor:@Before 注解對應通知 AspectJMethodBeforeAdvice 對應的環繞通知。
  • AfterReturningAdviceInterceptor:@AfterReturning 注解對應通知 AspectJAfterReturningAdvice 對應的環繞通知。

2 使用方式

??spring aop 可以使用 xml、接口實現、注解 三種方式進行配置,其中前兩種為 spring aop 提供,第三種為 AspectJ 提供。

2.1 接口實現配置

??用接口實現的方式使用 aop,主要是實現切面、切點、通知相關的接口。如切面 Advisor;切點 Pointcut;通知 MethodBeforeAdvice、AfterReturningAdvice、AfterThrwosAdvice、AfterAdvice、MethodInterceptor。

// 目標類 @Component public class Zed {public void attack() {System.out.println("Zed attack()");}public void taunt() {System.out.println("Zed taunt()");} } @Configuration public class SpringAop {// 前置通知@Beanpublic MethodBeforeAdvice beforeAdvice() {return (method, args, target) -> {System.out.println("Spring aop 前置通知");};}// Zed attack() 方法的前置通知 切面@Beanpublic Advisor before(MethodBeforeAdvice beforeAdvice) {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("execution(public * org.xgllhz.spring.aop.test.Zed.attack())");return new DefaultPointcutAdvisor(pointcut, beforeAdvice);}// 環繞通知@Beanpublic MethodInterceptor aroundAdvice() {return invocation -> {System.out.println("Spring aop 前環繞通知");Object result = invocation.proceed();System.out.println("Spring aop 后環繞通知");return result;};}// Zed taunt() 方法的環繞通知 切面@Beanpublic Advisor around(MethodInterceptor aroundAdvice) {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("execution(public * org.xgllhz.spring.aop.test.Zed.taunt())");return new DefaultPointcutAdvisor(pointcut, aroundAdvice);} } // 測試結果 Spring aop 前置通知 Zed attack()Spring aop 前環繞通知 Zed taunt() Spring aop 后環繞通知

2.2 注解配置

??用注解方式使用 spring aop,主要是使用切點、通知相關的注解。如切點 @Pointcut;通知 @Before、@AfterReturning、@AfterThrows、@After、@Around。這些源自 AspectJ 實現的 aop 中,但 spring aop 適配了這些注解,使得可以在 spring aop 中使用這些注解來配置 aop。

// 目標類 @Component public class Fizz {public void attack() {System.out.println("Fizz attack()");}public void taunt() {System.out.println("Fizz taunt()");} } @Aspect @Component public class AspectJAop {// 切點@Pointcut("execution(public * org.xgllhz.spring.aop.test.Fizz.attack())")public void attackPointcut() {}// 前置通知@Before("attackPointcut()")public void beforeAdvice() {System.out.println("AspectJ 前置通知");}// 切點@Pointcut("execution(public * org.xgllhz.spring.aop.test.Fizz.taunt())")public void tauntPointcut() {}// 環繞通知@Around("tauntPointcut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("AspectJ 前環繞通知");Object result = joinPoint.proceed();System.out.println("AspectJ 后環繞通知");return result;} } // 測試結果 AspectJ 前置通知 Fizz attack()AspectJ 前環繞通知 Fizz taunt() AspectJ 后環繞通知

3 jdk 與 cglib 動態代理

??spring aop 底層基于動態代理,即 jdk 動態代理和 cglib 動態代理。

3.1 jdk 動態代理

3.1.1 簡介

??jdk 動態代理即由 jdk 的 java.lang.reflect 包中的 Proxy、InvocationHandler、ProxyGenerator 等類提供的生成代理對象的功能。

??jdk 動態代理要求被代理的目標類必須實現一個或多個接口,這也是 jdk 動態代理的限制所在,即未實現接口的類無法被 jdk 動態代理。同時,jdk 動態代理是基于接口實現的(亦或是方法實現),所以目標類中的成員變量、static 方法、final 方法、private 方法均不能被其代理。也可以理解為 jdk 動態代理是基于方法實現的。

3.1.2 使用示例
// 接口 public interface Hero {void attack(); } // 目標類 public class Zed implements Hero {@Overridepublic void attack() {System.out.println("invoke target method");} } public class JdkProxyTest {public static void main(String[] args) {// 目標對象Hero target = new Zed();// 類加載器 負責在運行期間加載動態生成的代理類的字節碼文件ClassLoader classLoader = JdkProxyTest.class.getClassLoader();// 生成代理對象Hero proxyInstance = (Hero) Proxy.newProxyInstance(classLoader, new Class[]{ Hero.class }, (proxy, method, args1) -> {System.out.println("前置增強");// invoke() 方法的第一個參數是目標對象 第二個是目標對象的方法的參數Object result = method.invoke(target, args1);System.out.println("后置增強");return result;});proxyInstance.attack();} } // 測試結果 前置增強 invoke target method 后置增強

??如上述代碼所示,Hero 為目標類要實現的接口,Zed 為目標類,attack() 方法為要代理的方法。jdk 動態代理的核心是 Proxy 類和 InvocationHandler 接口,其中 Proxy 父類生成代理對象,InvocationHanlder 接口負責提供要增強的內容及目標方法的調用。獲取代理對象的方法為 Proxy 類的 newProxyInstance() 方法,為靜態方法,其需要三個參數,分別是 ClassLoader、Class<?>[]、InvocationHandler。其中 ClassLoader 負責在運行期間加載動態生成的代理類的字節碼文件(實際上是個 byte 數組);Class<? >[] 則為目標類實現的接口;InvocationHandler 則為增強內容。

??jdk 動態代理其核心為代理對象的創建,亦可為代理類的動態生成。代理類類對象由 Proxy 的內部類 ProxyBuilder 的靜態方法 defineProxyClass() 生成,在這里會按一定規則生成代理類的類名,然后調用 ProxyGenerator 的 generateProxyClass() 方法生成代理類的字節碼數組,接著調用 Unsafe 類的 defineClass() 方法生成代理類的類對象。

// 獲取代理對象 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {Objects.requireNonNull(h);final Class<?> caller = System.getSecurityManager() == null? null: Reflection.getCallerClass();// 查找或生成指定代理類的構造器Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);// 根據代理類構造器及 InvocationHanlder 生成代理對象return newProxyInstance(caller, cons, h); } // Proxy.ProxyBuilder 獲取代理類的類對象 private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {// 按照規則生成代理類類名 形如 $ProxyN 其中 N 代表第 N 次生成代理類long num = nextUniqueNumber.getAndIncrement();String proxyName = proxyPkg.isEmpty()? proxyClassNamePrefix + num: proxyPkg + "." + proxyClassNamePrefix + num;ClassLoader loader = getLoader(m);trace(proxyName, m, loader, interfaces);// 調用 ProxyGenerator.generateProxyClass 方法生成代理類的字節碼數組// 其接受三個參數 分別為代理類類名、要實現的接口名、訪問權限byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);try {// 調用 UNSAFE.defineClass() 生成代理類對象Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,0, proxyClassFile.length,loader, null);reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);return pc;} catch (ClassFormatError e) {throw new IllegalArgumentException(e.toString());} }
3.1.3 模擬實現

??模擬實現 jdk 動態代理,主要在于最后生成的代理類。

// 目標類要實現的接口 public interface Hero {Object attack(); } // 目標類 public class ZedHero implements Hero {@Overridepublic Object attack() {System.out.println("執行目標方法");return "zed";} } // 模仿 InvocationHandler 接口 public interface InvocationHandler {Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } // 最終生成的代理類 public class $Proxy0 implements Hero {private InvocationHandler handler; // 所持有的調用處理器對象private static Method attack; // 被代理的 attack 方法對象// 在靜態代碼塊中通過反射從目標類實現的接口的獲取到要代理的方法對象static {try {attack = Hero.class.getDeclaredMethod("attack");} catch (NoSuchMethodException e) {throw new NoSuchMethodError(e.getMessage());}}// 有參構造 接受一個調用處理器對象參數public $Proxy0(InvocationHandler handler) {this.handler = handler;}// 最終被代理的 attack 方法@Overridepublic Object attack() {try {// 內部直接調用 InvocationHanlder 的 invoke() 發方法// 而 invoke() 方法內不僅會調用目標類的 attack() 方法 還會執行增強邏輯return this.handler.invoke(this,attack, null);} catch (RuntimeException | Error e) {throw e;} catch (Throwable e) {throw new UnsupportedOperationException(e);}} }
3.1.4 反射優化

??jdk 動態代理中是通過反射來調用目標對象的方法的。眾所周知,java 中反射是存在性能問題的,所以 jdk 對其作出了優化。即當反射調用某一個方法時,默認情況下前 15 次調用都是反射調用(實際上是通過 DelegatingMethodAccessorImpl/NativeMethodAccessorImpl 實例調用的),從第 16 次開始則會給反射調用的方法生成一個方法訪問類(即 GeneratedMethodAccessorXXX 類)(此處可理解為直接調用方法而非反射),再調用該方法時則會用該類實例以直接調用的方式調用。反射調用次數可通過 -Dsun.reflect.inflationThreshold=xxx 莫命令來指定,也可通過 -Dsun.reflect.noInflation=true 來忽略前十五次的反射調用,從直接調用開始(jdk 為什么不直接將其設置為 true,這樣就可以避免反射了么。而 jdk 沒有這么做的原因是 jdk 或其它 java 框架中多次使用了反射,若為 false,則會給每個反射調用的方法生成一個 GeneratedMethodAccessorXXX 類,這樣會使類爆炸,大量占用內存(僅個人理解))。

public class MethodInvokeTest {public static void attack(Integer i) {System.out.println("瞬獄影殺陣 " + i);}// 方法反射調用時 底層使用 MethodAccessor 實現類private static void show(int i, Method foo) throws Exception {Method getMethodAccessor = Method.class.getDeclaredMethod("getMethodAccessor");getMethodAccessor.setAccessible(true);Object invoke = getMethodAccessor.invoke(foo);if (invoke == null) {System.out.println(i + ":" + null);return;}Field delegate = Class.forName("jdk.internal.reflect.DelegatingMethodAccessorImpl").getDeclaredField("delegate");delegate.setAccessible(true);System.out.println(i + ":" + delegate.get(invoke));}public static void main(String[] args) throws Exception {Method attackMethod = MethodInvokeTest.class.getDeclaredMethod("attack", Integer.class);for (int i = 1; i <= 17; i++) {attackMethod.invoke(null, i);show(i, attackMethod);}} } // 測試結果 // 從結果可看出 前 15 次都是使用 NativeMethodAccessorImpl 實例反射調用 // 從第 16 次開始使用 GeneratedMethodAccessor1 實例 而 GeneratedMethodAccessor1 的調用方式為直接調用 // 注:該測試需要添加 jvm 參數 // --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED 瞬獄影殺陣 1:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 2:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 3:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 4:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 5:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 6:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 7:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 8:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 9:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 10:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 11:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 12:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 13:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 14:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 15:jdk.internal.reflect.NativeMethodAccessorImpl@224edc67 瞬獄影殺陣 16:jdk.internal.reflect.GeneratedMethodAccessor1@6f7fd0e6 瞬獄影殺陣 17:jdk.internal.reflect.GeneratedMethodAccessor1@6f7fd0e6

3.2 cglib 動態代理

3.2.1 簡介

??cglib 是一個強大的高性能代碼生成包,它可以在運行期擴展 java 類或實現 java 接口,被廣泛應用于許多 aop 框架,如 spring aop、dynaop。其底層使用一個小而快的字節碼處理框架 asm,通過 asm 來轉換字節碼并生成類。

??cglib 動態代理是基于繼承實現的,即其是通過繼承目標類來生成一個代理類。所以目標類中的成員變量、static 方法、final 方法、private 方法是不能被其代理的。也可以理解為 cglib 動態代理是基于方法重寫的。

3.2.2 使用示例
// 目標類 public class Zed {public void attack() {System.out.println("Zed attack()")} } public class CglibProxyTest {public static void main(String[] args) {// 目標對象Zed target = new Zed();// 代理對象// create() 第一個參數是代理父類型 第二個參數是回調(這里使用一個回調接口的子接口)// 回調方法的第一個參數是代理對象 第二個參數是目標方法 第三個參數是目標方法入參 第四個參數是目標方法的代理方法對象Target proxyInstance = (Target) Enhancer.create(Zed.class, (MethodInterceptor) (proxy, method, objects, methodProxy) -> {System.out.println("前置增強");// 內部使用代理Object result1 = method.invoke(target, objects);// 內部未使用代理Object result2 = methodProxy.invoke(target, objects);// 內部未使用代理Object result3 = methodProxy.invokeSuper(proxy, objects);System.out.println("后置增強");return result1;});proxyInstance.attack();} } // 測試結果 前置增強 Zed attack() 后置增強

??如上述代碼所示,cglib 動態代理是通過 Enhancer 類的靜態方法 create() 來獲取代理對象的,該方法接受兩個參數,分別代表目標類、回調接口,其中目標類是作為父類在生成代理類時被用來繼承,而回調接口則是承載了增強代碼和目標方法的調用。

??與 jdk 動態代理的另一不同點在于目標方法的調用。jdk 動態代理中是直接通過反射來調用目標方法,而 cglib 則提供了三種目標方法的調用方式:

  • method.invoke(target, objects):其和 jdk 動態代理類似,直接在內部使用反射來調用目標方法。第一個參數為目標對象,第二個參數為目標方法的參數。
  • methodProxy.invoke(target, objects):其未使用反射,它會正常(間接)調用目標方法。第一個參數為目標對象,第二個參數為目標方法參數。spring 即采用這方方式。
  • methodProxy.invokeSuper(proxy, objects):其未使用反射,它會正常(間接)調用目標方法。第一個參數為代理對象,第二個參數為目標方法參數。其省略了目標對象。
3.2.3 模擬實現

??模擬 cglib 動態代理,重點在于最后生成的代理類。

// 目標類 public class Zed {public void attack() {System.out.println("影忍法·滅魂劫");}public void attack(Integer q) {System.out.println("影奧義·諸刃 " + q);} } // 模擬方法攔截器 即回調接口 public interface MethodInterceptor {// 代理方法 參數分別為:代理對象、目標方法、目標方法參數、目標方法代理對象Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable;} // 最后生成的代理類 public class CglibProxy extends Zed {// 代理類內部持有方法攔截器的實例 通過其來調目標方法private MethodInterceptor methodInterceptor;public CglibProxy() {}// 代理類內部持有了目標方法的方法對象private static Method method0;private static Method method1;// 代理類在內部持有了目標方法的代理對象private static MethodProxy methodProxy0;private static MethodProxy methodProxy1;static {try {// 在靜態代碼塊中實例化目標方法對象method0 = Zed.class.getDeclaredMethod("attack");method1 = Zed.class.getDeclaredMethod("attack", Integer.class);// 在靜態代碼塊中實例化目標方法的代理對象 通過 MethodProxy 的靜態方法 create() 來獲得// create() 方法接受四個參數,分別是目標類、cglib代理類、目標方法參數及返回值描述、目標方法名稱,代理方法名稱// 其中目標方法參數及返回值描述 形如 '(Q)V'// 其通過 jvm 指令解析 形如 (Q)V 表示返回值為 void 入參只有一個(目前還沒深入研究)methodProxy0 = MethodProxy.create(Zed.class, CglibProxy.class, "()V", "attack", "attackSuper");methodProxy1 = MethodProxy.create(Zed.class, CglibProxy.class, "(Q)V", "attack", "attackSuper");} catch (NoSuchMethodException e) {throw new NoSuchMethodError(e.getMessage());}}public void setMethodInterceptor(MethodInterceptor methodInterceptor) {this.methodInterceptor = methodInterceptor;}// 以下這兩個方法是為反射優化準備的public void attackSuper() {super.attack();}public void attackSuper(Integer q) {super.attack(q);}// 重寫了目標類的目標方法 并在其內部通過方法攔截器來間接調用目標方法@Overridepublic void attack() {try {this.methodInterceptor.intercept(this, method0, new Object[0], methodProxy0);} catch (Throwable e) {throw new UndeclaredThrowableException(e);}}@Overridepublic void attack(Integer q) {try {this.methodInterceptor.intercept(this, method1, new Object[]{q}, methodProxy1);} catch (Throwable e) {throw new UndeclaredThrowableException(e);}} }
3.2.4 反射優化

??與 jdk 動態代理一樣,cglib 動態代理中也使用了反射來調用目標對象的方法,所以其也會存在反射性能的問題。

??首先,cglib 調用目標方法有三種方式:

  • method.invoke(target, objects):使用反射調用,調用足夠多的次數才會進行優化。
  • methodProxy.invoke(target, objects):未使用反射,間接調用。結合目標對象使用。spring 采用這種調用方式。
  • methodProxy.invokeSuper(proxy, objects):未使用反射,間接調用。結合代理對象使用。

而 cglib 不同于 jdk 的反射優化方式就在于后兩種調用方式,即結合目標對象調用和結合代理對象調用。其優化思想是為目標方法額外生成代理類。即當調用 MethodProxy 的 invoke() 或 invokeSuper() 方法是會額外生成兩個代理類(可以稱之為方法代理類),分別是 TargetFastClassProxy 和 ProxyFastCassProxy。其中 TargetFastClassProxy 方法代理類是直接為目標類生成的方法代理類,而 ProxyFastClassProxy 則是為目標類的代理類的方法(具體是代理類中的后綴為 Super 的方法)生成的方法代理類。二者思想大同小異,都是通過代理類在代理類內部直接調用目標類的方法。

??所以,對于 cglib 動態代理,則可能會生成三個代理類,分別是目標類的代理類、目標方法的代理類、目標類的代理類的目標方法的代理類。

??就上述實例代碼而言,其最終生成的 TargetFastClassProxy 類和 ProxyFastClassProxy 類如下:

public class TargetFastClassProxy {// 記錄了目標類的目標方法的簽名static Signature signature0 = new Signature("attack", "()V");static Signature signature1 = new Signature("attack", "(Q)V");// 通過方法簽名來獲取方法編號(此處方法編號是固定的)public int getIndex(Signature signature) {if (signature0.equals(signature)) {return 0;} else if (signature1.equals(signature)) {return 1;} else {return -1;}}// 通過方法編號來調用對應的目標方法public Object invoke(int index, Object target, Object[] args) {if (0 == index) {// 此處是直接使用目標對象來調用目標方法 而非反射的方式((Zed) target).attack();return null;} else if (1 == index) {((Zed) target).attack((Integer) args[0]);return null;} else {throw new RuntimeException("Method doest not exist");}}// 測試public static void main(String[] args) {TargetFastClassProxy targetFastClassProxy = new TargetFastClassProxy();int index = targetFastClassProxy.getIndex(new Signature("attack", "()V"));targetFastClassProxy.invoke(index, new Target(), null);} } public class ProxyFastClassProxy {// 記錄了目標類的代理類的目標方法的簽名// 仔細回憶下 在 3.2.2 使用示例中是不是有個類叫 CglibProxy 它里面是不是有兩個方法分別是 attackSuper() 和 attackSuper()// 這兩個方法就是被這個代理類代理的方法static Signature signature0 = new Signature("attackSuper", "()V");static Signature signature1 = new Signature("attackSuper", "(Q)V");// 通過方法簽名獲取方法編號public int getIndex(Signature signature) {if (signature0.equals(signature)) {return 0;} else if (signature1.equals(signature)) {return 1;} else {return -1;}}// 通過方法編號來調用指定方法public Object invoke(int index, Object proxy, Object[] args) {if (0 == index) {// 這里是直接使用代理對象來調用// 而 CglibProxy 的 attackSuper() 方法內部則是直接使用目標對象調用了目標方法 整個流程也是非反射的((CglibProxy) proxy).attackSuper();return null;} else if (1 == index) {((CglibProxy) proxy).attackSuper((Integer) args[0]);return null;} else {throw new RuntimeException("Method doest not exist");}}// 測試public static void main(String[] args) {ProxyFastClassProxy proxyFastClassProxy = new ProxyFastClassProxy();int index = proxyFastClassProxy.getIndex(new Signature("attackSuper", "()V"));proxyFastClassProxy.invoke(index, new CglibProxy(), null);} }

3.3 jdk 與 cglib 反射優化

??通過上述案例,則可知 jdk 與 cglib 在針對反射性能問題上的優化的異同點:

  • 相同點
    • 1、二者都是通過生成額外的代理類實現的(即方法代理類)。
    • 2、二者的優化手段都是通過直接調用目標對象的方法。
  • 不同點
    • 1、jdk 是在目標方法被調用了 15 后才生成額外的代理類的,而 cglib 則是在第一次調用目標方法時就生成了額外的代理類(即 TargetFastClassProxy 或 ProxyFastClassProxy)。
    • 2、jdk 會為每一個目標方法都生成額外的代理類,而 cglib 則會為目標類的所有目標方法或代理類所有目標方法只生成一個額外的代理類。

4 spring aop 與動態代理

??spring aop 底層基于 jdk 動態代理和 cglib 動態代理,其是通過一系列的配置和接口以及實現類來統一了 jdk 和 cglib 的動態代理實現。

  • ProxyConfig

    即代理配置類,亦是代理配置的父類,即允許其它配置類對其進行繼承擴展,如許多 ProxyCreator 代理創建器類都會根據自身實際使用場景對其進行自定義配置。其主要成員變量如下:

    // 表示是否基于完整的類創建代理 即為 true 時使用 cglib 為 false 時使用 jdk 默認為 false private boolean proxyTargetClass = false;// 表示是否對代理進行優化 為 true 時表示優化 默認為 false(但具體怎么優化 從哪里優化沒研究過) private boolean optimize = false;// 表示是否應該凍結代理配置 代理配置被凍結后將不能再進行修改 即為 true 時將凍結 默認為 false private boolean forzen = false;// 表示生成的代理對象是否可以強轉為 Advised 實例 即為 true 時不可以 為 false 時可以 默認為 false 強轉為 Advised 實例后可獲取一些代理相關的信息 boolean opaque = false;// 表示生成的代理對象是否可以被 aop 的 AopContext 的 ThreadLocal 線程局部變量共享出去(共享的目的是為了目標對象能夠訪問) 即為 true 時將共享 默認為 false boolean exposeProxy = false;
  • Advised

    即切面接口。實際上它和切面關系不大,更像是一個綜合性功能的接口,聲明了許多功能性的方法,可通過此接口來獲取代理配置、代理對象的相關信息。且當 ProxyConfig 的 opaque 配置為 true 時,凡是通過 spring aop 生成的代理對象都可強轉為 Advised 類型。

    // 獲取代理配置是否被凍結 boolean isFrozen();// 獲取代理是否基于完整的類而不是接口 boolean isProxyTargetClass();// 獲取代理是否將被暴露 boolean isExposeProxy();// 獲取被代理的所有接口類型(即目標類實現的接口)(不包括被代理的類類型) Class<?>[] getProxiedInterfaces();// 判斷一個指定的類型是否為被代理的接口類型 boolean isInterfaceProxied(Class<?> intf);// 獲取代理對象的目標類 TargetSource getTargetSource();// 獲取 aop 中所有的切面(切面 = 切點 + 通知) Advisor[] getAdvisors();// 向 aop 上下文中添加一個切面 void addAdvisor(Advisor advisor) throws AopConfigException;
  • AdvisedSupport

    即 Advised 接口的實現類,其除了實現 Advised 接口聲明的方法外,還維護了三個重要的成員變量,如下所示:

    // 目標類 默認為空 TargetSource = targetSource = EmptyTargetSource.INSTANCE;// 目標類所實現的接口類型集合 private List<Class<?>> interfaces = new ArrayList<>();// 從目標類中解析出來的切面集合 目標類中配置的所有通知最終會被解析成單個的 Advisor 切面并被維護在該集合中 private List<Advisor> advisors = new ArrayList<>();
  • ProxyCreatorSupport

    其繼承自 AdvisedSupport,除了擁有父類的相關功能外,其最重要的一點是持有一個 AopProxyFactory 成員變量,并對外提供了該變量相關的方法。該成員變量意為 aop 代理工廠,即提供一個創建代理的工廠。

    // AopProxyFactory aop 代理工廠 private AopProxyFactory aopProxyFactory;
  • ProxyFactory

    即代理工廠,其繼承自 ProxyCreatorSupport,其最重要的功能配置特定的代理工廠并使用工廠獲取代理對象。

    // 先通過 AopProxyFactory 的 createAopProxy() 方法獲取具體的動態代理實現(即 AopProxy 的實例) // 然后再通過 AopProxy 的 getProxy() 方法創建代理對象 public Object getProxy() {return createAopProxy().getProxy(); }// 基于 jdk 動態代理獲取代理對象 public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {return (T) new ProxyFactory(proxyInterface, targetSource).getProxy(); }// 基于 cglib 動態代理獲取代理對象 public static Object getProxy(TargetSource targetSource) {ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTargetSource(targetSource);proxyFactory.setProxyTargetClass(true);return proxyFactory.getProxy(); }
  • AopProxyFactory

    即 aop 代理工廠接口,主要功能是獲取一個 aop 代理實現。注意 AopProxyFactory 和 ProxyFactory 的區別,AopProxyFactory 工廠是用來生產一個 aop 代理實現的,如 jdk 動態代理、cglib 動態代理;而 ProxyFactory 工廠是用來生產代理對象的。AopProxyFactory 接口只有一個功能,如下:

    // 根據傳入的代理配置獲取一個 aop 代理實現 如 jdk 動態代理、cglib 動態代理 AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
  • DefaultAopProxyFactory

    即 AopProxyFactory 接口的默認實現類,其主要實現了接口中的 createAopProxy() 方法。因此此處是決定 sping aop 最終使用那種動態代理實現的關鍵。

    // 根據指定的配置獲取創建一個 aop 代理實現 @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (!NativeDetector.inNativeImage() &&(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("");}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {// 若目標類是個接口、代理類、lambda 表達式 則返回 jdk 動態代理實現return new JdkDynamicAopProxy(config);}// 若代理需要被優化、基于完整的類創建代理、代理配置未基于接口 則返回 cglib 動態代理實現return new ObjenesisCglibAopProxy(config);}else {// 若代理不需要被優化、不是基于完整類創建代理、代理配置基于接口 則返回 jdk 動態代理實現return new JdkDynamicAopProxy(config);} }
  • AopProxy

    即 aop 代理接口,該接口定義了實際獲取代理對象的功能。且 spring 提供了兩個實現類,分別是 JdkDynamicAopProxy 和 CglibAopProxy,即分別代表 jdk 動態代理和 cglib 動態代理。

    public interface AopProxy {Object getProxy();Object getProxy(@Nullable ClassLoader classLoader); }
  • JdkDynamicAopProxy

    即 spring aop 實現的 jdk 動態代理。該類實現類 AopProxy 接口,用來創建代理對象;同時實現了 InvocationHandler 接口,用來回調目標方法,其中目標方法是以反射的方式調用。

    final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {// 構造方法 實例化了 Advised 實例和目標類所實現的接口public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {this.advised = config;this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);}@Overridepublic Object getProxy() {return getProxy(ClassUtils.getDefaultClassLoader());}@Overridepublic Object getProxy(@Nullable ClassLoader classLoader) {// 使用 Proxy 類的靜態方法 newProxyInstance() 創建代理對象return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);}// 回調方法 內部以反射的方式調用了目標方法@Override@Nullablepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {..} }
  • CglibAopProxy

    即 spring aop 實現的 cglib 動態代理類,該類實現了 AopProxy 接口。內部通過 Enhancer 的 create() 方法來創建代理對象。同時定義了內部類 DynamicAdvisedInterceptor,其實現了 MethodInterceptor 接口,來作為回調接口的實現,內部通過 MethodProxy#invoke(Object Target, Object[] objects) 方法來以非反射的方式調用目標方法。

    class CglibAopProxy implements AopProxy, Serializable {public CglibAopProxy(AdvisedSupport config) throws AopConfigException {this.advised = config;this.advisedDispatcher = new AdvisedDispatcher(this.advised);}@Overridepublic Object getProxy() {return getProxy(null);}@Overridepublic Object getProxy(@Nullable ClassLoader classLoader) {...// 配置 cglib EnhancerEnhancer enhancer = createEnhancer();enhancer.setSuperclass(proxySuperClass);enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));// 獲取回調(其定義了多個回調內部實現類 如 equals() 的、hashCode() 的、動態代理的)Callback[] callbacks = getCallbacks(rootClass);enhancer.setCallbackTypes(types);// 創建代理類和代理對象return createProxyClassAndInstance(enhancer, callbacks);}protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {enhancer.setInterceptDuringConstruction(false);enhancer.setCallbacks(callbacks);return (this.constructorArgs != null && this.constructorArgTypes != null ?enhancer.create(this.constructorArgTypes, this.constructorArgs) :enhancer.create());}// 在回調接口的內部實現類中調用了此靜態方法 在此方法內調用了方法代理類的 invoke() 方法(該方法是以非反射的方式調用目標方法)@Nullableprivate static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)throws Throwable {return methodProxy.invoke(target, args);} }

5 從 @Aspect 到 Advisor

??前文中提到了 spring aop 的使用方式,即接口實現配置和注解配置。其中接口實現配置是通過直接實現 spring aop 提供的相關切點、通知、切面接口來使用 aop 的;而注解配置則是使用了 spring aop 集成自 AspectJ 框架的相關注解來使用 aop 的。

??這兩者之間是存在緊密聯系的,即 spring aop 會將通過注解配置的切面轉換成相關接口實例。具體則是 @Aspect 到 Advisor 的過程。這里我們可以將通過注解配置的切面稱之為高級切面,將通過實現接口配置的切面稱之為低級切面。而這個轉換工作則是由 AnnotationAwareAspectJAutoProxyCreator BPP 來完成的。

??AnnotationAwareAspectJAutoProxyCreator BPP 主要有兩個功能:

  • 切面轉換

    即將 @AspectJ 高級切面轉換為 Advisor 低級切面,由 findEligibleAdvisors() 方法來完成。該方法會找到兩種切面,一種是通過直接實現 Advisor 接口實現的低級切面,一種是通過解析 @AspectJ 高級切面得到的低級切面 Advisor。最終返回一個 List< Advisor> 集合。

  • 創建代理

    即創建代理對象。由 wrapIfNecessary() 方法完成。該方法會先通過調用 findEligibleAdvisors() 方法獲得所有的低級切面,然后為其創建代理。創建代理的時機在 spring bean 生命周期中表現為:實例化 -> (1) 屬性設置 -> 初始化 (2),即創建代理的時機為:當發生循環依賴時在屬性設置(依賴注入)前創建代理;當未發生循環依賴時在初始化后創建代理。

6 通知順序

??通知順序由具體的切面使用決定,分為兩種,即低級切面和高級切面。具體順序如下:

  • 低級切面

    低級切面的通知順序需要借助 @Order 注解來設置,其值越小通知越早。注:該注解只能作用于類,作用于方法無效。

  • 高級切面

    高級切面由具體的通知注解決定,即 @Around before、@Before、@AfterThrowing、@AfterReturning、@After、@Around after。分別表示為:前環繞通知、前置通知、異常后通知、返回后通知、后置通知、后環繞通知。

7 靜態通知調用與動態通知調用

??所謂靜態通知調用指的時目標方法與通知方法之間不存在參數傳遞的情況,而動態通知調用則指的是目標方法與通知方法之間存在參數傳遞的情況。這里的參數傳遞是指將目標方法的參數綁定到通知方法上。

7.1 靜態通知調用

??靜態通知調用的流程為(以 jdk 動態代理為例):

  • a 切面轉換

    即將 @Aspect 注解標注的高級切面轉換成 Advisor 低級切面。

    • @Around 切面通知被解析為 Advisor 的子實現類 AspectJAroundAdvice。
    • @Before 切面通知被解析為 Advisor 的子實現類 AspectJMethodBeforeAdvice。
    • @AfterThrowing 切面通知被解析為 Advisor 的子實現類 AspectJAfterThrowingAdvice。
    • @AfterReturning 切面通知被解析為 Advisor 的子實現類 AspectJAfterReturningAdvice。
    • @After 切面通知被解析為 Advisor 的子實現類 AspectJAfterAdvice。
  • b 通知轉換

    即將非環繞通知轉換為環繞通知。這里的環繞通知是指 MethodInterceptor 類型(org.aopalliance.intercept.MethodInterceptor)。

    ProxyFactory 會將非環繞通知轉換為環繞通知,且通知調用時會以 MethodInterceptor 類型調用。

    而通過 @Aspect 注解配置的切面中的部分通知不是環繞通知,如 @Before、@AfterReturning。所以此處 spring aop 運用適配器模式將非環繞通知轉換成了環繞通知。

    • MethodBeforeAdviceAdapter 將 @Before 對應的通知 AspectJMethodBeforeAdvice 適配為 MethodBeforfeAdviceInterceptor。
    • AfterReturningAdviceAdapter 將 @AfterReturning 對應的通知 AspectJAfterReturningAdvice 適配為 AfterReturningAdviceInterceptor。
  • c 通知調用

    由 MethodInvocation 接口調用通知。因為方法存在嵌套情況,通知又基于方法,所以通知也存在嵌套情況,故此處使用責任鏈模式來調用。即調用順序為 由外而內 -> 目標方法 -> 由內而外。

7.2 動態通知調用

??動態通知調用即目標方法與通知方法之間存在參數傳遞的情況(將目標方法的參數綁定到通知方法上)。調用流程與靜態通知調用的區別在于通知轉換上,即其在通過代理工廠將非環繞通知轉換到環繞通知時(ProxyFactory.getInterceptorsAndDynamicInterceptionAdvice()),將動態通知轉化成了 InterceptorAndDynamicMethodMatcher 類型。該類型中維護了環繞通知和切點成員變量,即 MethodInterceptor 和 MethodMatcher。其中 MethodMatcher 是表達式切點 AspectJExpressionPointcut 的父接口。從而實現了動態通知調用。

??注:動態通知調用需要再次解析切點以便為通知方法綁定參數,故其復雜度較高,較靜態通知調用而言性能較差。

8 通知調用 MethodInvocation

??在 spring aop 中,以 jdk 動態代理為例,通知調用采用了責任鏈設計模式,其中每一個通知(MethodInterceptor)都代表一個職責,所有的通知會組成一個通知鏈(MethodInvocation),且在最中間調用了目標方法。

??責任鏈設計模式在 java 和 spring 框架中有很多的引用,常用在過濾器、攔截器中。如 servlet 中的過濾器,主要體現在 FilterChain 與 Filter 中;spring security 中的 SpringSecurityChain 與 Filter;spring aop 中的 MethodInvocation 與 MethodInterceptor 等。

??以下將模擬實現 spring aop 通知調用的工作流程:由外而內 -> 目標方法 -> 由內而外。

// 目標類 public class Zed {// 目標方法public void attack() {System.out.println("禁奧義·瞬獄影殺陣");} } // 通知一 public class OneAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("OneAdvice 環繞前通知");Object result = invocation.proceed();System.out.println("OneAdvice 環繞后通知");return result;} }// 通知二 public class TwoAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("TwoAdvice 環繞前通知");Object result = invocation.proceed();System.out.println("TwoAdvice 環繞后通知");return result;} }// 通知三 public class ThreeAdvice implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("ThreeAdvice 環繞前通知");Object result = invocation.proceed();System.out.println("ThreeAdvice 環繞后通知");return result;} } // 自定義實現 MethodInvocation(這個可以理解為 通知鏈) public class MyMethodInvocation implements MethodInvocation {private Object target; // 目標對象private Method method; // 目標方法private Object[] args; // 目標方法參數private List<MethodInterceptor> methodInterceptors; // 通知集合(環繞通知集合)private int count = 1; // 通知調用次數 因為中間會調用一次目標方法 調用目標方法時不會調用通知 所在其初始值為 1public MyMethodInvocation(Object target, Method method, Object[] args, List<MethodInterceptor> methodInterceptors) {this.target = target;this.method = method;this.args = args;this.methodInterceptors = methodInterceptors;}@Overridepublic Method getMethod() {return this.method;}@Overridepublic Object[] getArguments() {return this.args;}@Overridepublic Object proceed() throws Throwable {// 若調用次數大于通知數量 則說明通知鏈中每個通知都已調用完畢(遞歸到最底層) 此時應該調用目標方法if (this.count > this.methodInterceptors.size()) {return this.method.invoke(this.target, this.args);}// 獲取通知鏈中下一個通知 然后調用MethodInterceptor interceptor = this.methodInterceptors.get(this.count++ - 1);return interceptor.invoke(this);}@Overridepublic Object getThis() {return this.target;}@Overridepublic AccessibleObject getStaticPart() {return this.method;} } // 測試 public class MethodInvocationTest {public static void main(String[] args) throws Throwable {// 構建一個通知鏈List<MethodInterceptor> methodInterceptors = List.of(new OneAdvice(), new TwoAdvice(), new ThreeAdvice());// 在目標對象的目標方法上調用通知鏈MyMethodInvocation methodInvocation = new MyMethodInvocation(new Zed(), Zed.class.getMethod("attack"),new Object[0], methodInterceptors);methodInvocation.proceed();} } // 測試結果 由結果可見 通知調用為 由外而內 -> 目標方法 -> 由內而外 OneAdvice 環繞前通知 TwoAdvice 環繞前通知 ThreeAdvice 環繞前通知 禁奧義·瞬獄影殺陣 ThreeAdvice 環繞后通知 TwoAdvice 環繞后通知 OneAdvice 環繞后通知

??難得 可以同座 何以 要忌諱赤裸

總結

以上是生活随笔為你收集整理的史上最烂 spring aop 原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

日韩精品久久久久久久电影99爱 | 欧美在线视频二区 | 91最新在线| 人人爽人人舔 | 成人av一区二区在线观看 | 国产福利精品视频 | 91 在线视频播放 | 日韩精品一区二区三区在线视频 | 中文字幕av全部资源www中文字幕在线观看 | 一区二区三区观看 | 人人插人人 | 久久女同性恋中文字幕 | 日韩在线短视频 | 91黄色小网站 | 国产91影视 | 日韩视频免费看 | 国产福利精品在线观看 | 国产精品久久久久久久毛片 | 日韩免费在线视频 | 精品在线视频一区 | 狠狠狠色| 日韩一级片大全 | 久草在线最新视频 | 四虎影视成人永久免费观看视频 | 五月天.com | 午夜色场 | 国内综合精品午夜久久资源 | 久久久久久久国产精品影院 | 日韩有码网站 | 五月天色中色 | 日日夜夜免费精品视频 | 激情丁香5月 | 久久亚洲在线 | 欧美超碰在线 | 人人网av | 一级a性色生活片久久毛片波多野 | 丁香在线视频 | 欧美黄色高清 | 不卡av免费在线观看 | 国产手机在线 | 91av视频导航 | 国内丰满少妇猛烈精品播放 | 久草在线免费看视频 | 激情校园亚洲 | 国产四虎影院 | 天天综合色天天综合 | 国产欧美精品一区二区三区四区 | 麻豆成人在线观看 | 国产精品视频全国免费观看 | 亚洲午夜av电影 | 在线观看国产区 | 中文字幕在线看 | 免费视频在线观看网站 | 成人a视频在线观看 | 最新日韩在线观看视频 | 成人啪啪18免费游戏链接 | 久久久成人精品 | 看片网站黄 | 狠狠狠色丁香婷婷综合久久五月 | 国产麻豆传媒 | 婷婷六月天天 | 日韩欧美亚洲 | 成人永久免费 | 91大神精品视频在线观看 | 久久婷婷色综合 | 国产精品电影一区 | 一本一本久久a久久精品综合小说 | 亚洲aⅴ乱码精品成人区 | 99精品视频在线播放免费 | 人人插人人玩 | 91黄色小网站 | 日韩欧美高清一区二区三区 | 黄色www免费| 香蕉在线观看 | 91热视频在线观看 | 欧美日韩中文另类 | 日韩高清精品免费观看 | 99国产免费网址 | 91精品免费视频 | 91你懂的 | 亚洲免费观看在线视频 | av久久在线 | 国产成人精品久久二区二区 | 日韩精品三区四区 | 狠狠色丁香久久婷婷综合_中 | 九九久久久久久久久激情 | 亚洲涩涩一区 | 激情视频国产 | 天天干天天插伊人网 | 在线中文字幕一区二区 | 久久久久免费精品国产小说色大师 | 国产91精品高清一区二区三区 | 国产不卡一二三区 | 亚洲乱亚洲乱妇 | 亚洲黄色区 | 中文一区在线 | 热re99久久精品国产66热 | 亚洲国产精品va在线 | 伊人在线视频 | www欧美xxxx| 18pao国产成视频永久免费 | 久久久影院一区二区三区 | 96亚洲精品久久久蜜桃 | 色五月成人 | 国产精品久久久久久久久久不蜜月 | 国产精品视频 | 欧美日韩久久不卡 | av黄色免费在线观看 | 国产精品一区二区中文字幕 | 婷婷色网| 日韩高清片 | 色播五月激情综合网 | 久久精品视频国产 | 最新中文字幕在线观看视频 | 久久精彩免费视频 | 韩日精品中文字幕 | 久久综合九色综合97婷婷女人 | 国产精品毛片久久久久久久 | 欧美成人tv| 伊人成人精品 | 91亚色视频在线观看 | 精品乱码一区二区三四区 | 欧美日韩高清不卡 | zzijzzij亚洲成熟少妇 | 久久国产高清 | 天天干天天玩天天操 | 中文字幕色在线视频 | 91在线视频导航 | 国产日产精品久久久久快鸭 | 久久视频6 | 爱情影院aqdy鲁丝片二区 | 日韩毛片精品 | 久久午夜精品影院一区 | 又污又黄网站 | 嫩草av影院 | 日韩高清无线码2023 | 久草视频在线资源 | 97人人模人人爽人人喊中文字 | 蜜臀av性久久久久av蜜臀妖精 | 亚洲区另类春色综合小说校园片 | 免费日韩av片 | 久久精品国产免费看久久精品 | 亚洲免费视频观看 | 人人草在线视频 | 国产一区影院 | 欧美男男激情videos | 中文字幕资源在线观看 | av观看在线观看 | 国产精品观看在线亚洲人成网 | 99精品免费久久久久久久久 | 在线播放91| 999久久久免费精品国产 | 中文字幕成人在线观看 | 日韩成人免费观看 | 国产在线色站 | 国产露脸91国语对白 | 久久av观看 | 久久久久这里只有精品 | 国产亚洲精品美女 | 狠狠操狠狠 | 天天射射天天 | 久久av中文字幕片 | 成人性生交大片免费看中文网站 | 亚洲激情一区二区三区 | 久要激情网 | 男女啪啪免费网站 | 日韩激情影院 | 96国产精品| 中文有码在线 | 久久天天操 | 久久久久欠精品国产毛片国产毛生 | 激情欧美日韩一区二区 | 99久久99久久免费精品蜜臀 | 国产精品18久久久久久久网站 | 国产精品国产三级国产 | 99久久精品免费看国产免费软件 | 天天干夜夜干 | 青草视频在线 | 国产精品99久久久久久小说 | 国产白浆在线观看 | 狠狠插狠狠干 | 色国产精品一区在线观看 | 色婷av| 91久久国产精品 | 国产亚洲欧美一区 | 婷婷久久网 | 麻豆传媒视频在线播放 | 国产精品中文久久久久久久 | www免费网站在线观看 | 亚州精品一二三区 | 亚洲国产高清视频 | 欧产日产国产69 | 午夜精品一区二区三区免费 | 中文字幕第一页在线 | 久久夜靖品 | 91在线一区二区 | 色婷婷视频在线 | 精品欧美一区二区三区久久久 | 久久精品韩国 | 亚洲免费在线看 | 国产中文字幕亚洲 | 伊人网综合在线观看 | 女人高潮一级片 | 国产精品青草综合久久久久99 | 国产精品99久久久久久久久 | 日韩av免费观看网站 | 91大神精品视频在线观看 | 欧美一二区视频 | 日韩视频1区 | 色爱区综合激月婷婷 | 欧美日bb | 九九欧美 | 免费情趣视频 | 福利视频网址 | 五月丁色 | 成人免费xyz网站 | 国产精品久久久久久久久免费 | 伊人天天综合 | 在线免费性生活片 | 黄色91免费观看 | 91女子私密保健养生少妇 | 中文字幕在线观看一区二区三区 | 欧美日韩中文在线观看 | 精品久久久久久亚洲综合网 | 国产伦精品一区二区三区免费 | 成人免费观看视频大全 | 日韩精品一区二区在线观看视频 | 日韩一级精品 | 日韩一区二区三区观看 | 91av中文字幕 | 超碰日韩 | 久久久久五月天 | 偷拍福利视频一区二区三区 | 色国产精品 | www.com久久| 91九色网站 | 中文在线字幕免费观 | 成人91av| 亚洲免费视频在线观看 | 成人在线观看免费 | 欧美精品亚洲精品 | 91综合久久一区二区 | 国内视频一区二区 | 手机色站 | 国产在线播放一区二区 | 麻豆视频免费在线 | 成人在线超碰 | 黄污视频大全 | 91在线精品一区二区 | 91亚洲精品视频 | 中文字幕在线观看第一区 | 国产 一区二区三区 在线 | 美女精品 | 在线观看免费福利 | 性色xxxxhd| 夜夜操天天 | 激情文学丁香 | 在线观看视频h | 在线天堂中文在线资源网 | 亚洲精品国产麻豆 | 日韩在线免费 | 国产美女精品在线 | 国产色秀视频 | 中文字幕在线免费播放 | 久久九九网站 | 日韩黄色在线电影 | 综合在线色 | 国产日韩欧美在线一区 | 日韩专区在线 | 亚洲在线视频免费观看 | 999视频网站| 综合天天久久 | 国产精品久久久久久久婷婷 | 国产夫妻自拍av | 亚洲在线视频网站 | 免费在线观看一区 | 最新高清无码专区 | 国产一区二区在线免费观看 | 五月天激情视频在线观看 | 日韩精品中文字幕在线观看 | 国产成人av一区二区三区在线观看 | 国产69精品久久久久9999apgf | 91精品国产91热久久久做人人 | 免费看的视频 | 超级碰碰碰视频 | 天天射射天天 | 久久综合九色综合欧美狠狠 | 久久久久久蜜av免费网站 | www久久九| 69欧美视频 | 国产精品久久久久久久久搜平片 | 在线播放 亚洲 | 久久综合九色综合久久久精品综合 | 丁香婷婷激情网 | 蜜臀aⅴ国产精品久久久国产 | 免费观看9x视频网站在线观看 | 久久久国产精华液 | 久久免费福利视频 | 国产精品视频免费在线观看 | 岛国av在线不卡 | 女人高潮一级片 | 亚洲性少妇性猛交wwww乱大交 | 久久精品专区 | 日韩视频免费 | 久久人人97超碰国产公开结果 | 99久久99久久精品国产片果冰 | 777视频在线观看 | 国产精品成人久久久 | 天天综合视频在线观看 | 9免费视频 | 日韩精品aaa | 欧美a在线免费观看 | 欧美日韩精品免费观看 | 狠狠夜夜| av三级在线免费观看 | 成年人视频在线观看免费 | 国产精品青草综合久久久久99 | 国产麻豆精品传媒av国产下载 | 国产一区二区三区久久久 | 日本天天操 | 麻豆一区在线观看 | 中文字幕在线看人 | 最近2019中文免费高清视频观看www99 | 国产精品黄色av | 色国产在线 | 九九热在线视频免费观看 | 激情av一区二区 | 色吊丝在线永久观看最新版本 | 99在线精品视频观看 | 在线观看岛国av | 天天摸天天干天天操天天射 | 亚洲天堂网站视频 | 久久超碰免费 | 国产精品xxxx18a99 | 成人h视频在线 | 国产中文字幕三区 | 美女网站在线观看 | 99精品视频一区 | 国产黄a三级三级 | 亚洲精品456在线播放第一页 | 在线看免费 | 欧美极品在线播放 | 国产字幕在线播放 | 日韩在线观看影院 | 亚洲精品国精品久久99热一 | 97品白浆高清久久久久久 | 日韩av中文字幕在线免费观看 | 99精品乱码国产在线观看 | 人人澡av| 婷婷激情站| 久久精品网址 | 99热精品久久 | 国产一区在线视频播放 | 国产日韩精品一区二区三区在线 | 国产成人精品日本亚洲999 | 色婷婷av一区 | 天天爱天天操天天射 | 69精品久久| 国产中年夫妇高潮精品视频 | 国产做aⅴ在线视频播放 | 亚洲成人精品 | 成人黄色影片在线 | 欧美在线观看视频一区二区 | 2022久久国产露脸精品国产 | 国产激情小视频在线观看 | 久久久久久97三级 | 粉嫩高清一区二区三区 | 最新免费av在线 | 中文字幕在线观看1 | 黄色成人av | 成年人在线免费看视频 | 欧美日本国产在线观看 | 黄色一级在线免费观看 | 在线观影网站 | 天天射天天爱天天干 | 日韩精品中文字幕在线不卡尤物 | 久久艹人人 | 国产精品久久久久免费 | av中文在线影视 | 日韩网站在线看片你懂的 | 久久www免费人成看片高清 | 国产在线资源 | 色欧美88888久久久久久影院 | 亚洲一区二区观看 | 国产精品18久久久久久不卡孕妇 | 九九99视频 | 日本黄色片一区二区 | 婷婷在线视频 | 九九视频精品免费 | 成年性视频 | 国产一区精品在线观看 | 亚洲jizzjizz日本少妇 | 999电影免费在线观看2020 | 久久久精品一区二区三区 | 黄色小说在线免费观看 | 久久综合久久综合九色 | 91av播放| 日韩高清一区 | 国产99在线| 婷婷久久一区二区三区 | 13日本xxxxxⅹxxx20 | 亚洲精品视频中文字幕 | 免费看麻豆 | 深夜激情影院 | 中文字幕一区二区三区四区久久 | 精品久久久久久亚洲 | 欧美中文字幕第一页 | 亚洲成av人影院 | 国产精品视频全国免费观看 | 麻豆一精品传二传媒短视频 | 91看毛片 | 亚洲精品视频在线观看免费视频 | 在线播放 日韩专区 | 日韩精品一区二区在线 | 久久天堂精品视频 | 五月天亚洲综合 | www日韩视频 | 国产韩国日本高清视频 | 日韩一区二区三区在线观看 | 人人玩人人爽 | 特级毛片在线免费观看 | 亚洲无人区小视频 | 久久99网 | 婷婷社区五月天 | 综合网五月天 | 色综合久久综合网 | 日韩视频图片 | 日韩三级视频在线观看 | 亚洲一区日韩精品 | av片中文 | 日韩免费专区 | 日韩电影在线一区 | 18国产精品白浆在线观看免费 | 国产99久久99热这里精品5 | 久久久久www | 国产精品黑丝在线观看 | 天天伊人狠狠 | 911亚洲精品第一 | 免费av福利| 亚洲四虎在线 | 久久兔费看a级 | 欧美在线aaa | 麻豆传媒视频在线 | 国产亚洲一区二区在线观看 | 99精品视频免费观看视频 | 国产一区二区三区免费视频 | av丝袜美腿 | 色婷婷激情五月 | 欧美成人91 | 日韩理论在线视频 | 91成品人影院 | 在线看日韩 | www.com久久| 亚洲精品国 | 亚洲精品成人网 | 亚洲天堂精品 | 色婷婷在线观看视频 | 在线免费观看麻豆视频 | 亚洲干 | 91九色网站 | 色婷婷亚洲精品 | 日本三级在线观看中文字 | 成年人在线免费看片 | 国产h在线观看 | 中文字幕在线视频一区二区 | 夜夜摸夜夜爽 | 人人爱爱| 国产中文字幕在线观看 | 一级性视频 | 美国三级黄色大片 | 在线日韩av | 亚洲精品动漫在线 | 国产精品原创 | 国产在线播放一区二区 | 国产一区在线视频播放 | 激情综合狠狠 | 欧洲视频一区 | 中日韩免费视频 | 97视频免费看 | 久久影视中文字幕 | 久久免费成人精品视频 | 在线观看黄a | 日韩欧美精品在线观看视频 | 欧女人精69xxxxxx | 一本到视频在线观看 | 啪啪午夜免费 | 激情综合网五月 | 欧美成年人在线视频 | 国产污视频在线观看 | 韩国av免费观看 | 欧美精品免费在线 | 麻豆传媒视频在线免费观看 | 黄色成人av | 国产精品一区专区欧美日韩 | 一区二区三区视频 | 日日夜夜天天 | 国产一区二区视频在线播放 | 91自拍91 | 国产涩图 | 成人免费中文字幕 | 久久久久亚洲精品男人的天堂 | 在线观看免费视频你懂的 | 丁香六月色 | 成人一区二区三区在线 | 国产剧情一区二区在线观看 | 亚洲精品三级 | 亚洲精品视频第一页 | 久久一区二区免费视频 | 欧洲不卡av| 亚洲精品66 | 欧美在线一 | 黄色软件在线观看 | 中文字幕av免费在线观看 | 久久精品综合 | 中文字幕日韩伦理 | 国产精品久久久久久吹潮天美传媒 | 婷婷亚洲综合五月天小说 | 日韩精品在线免费播放 | 国产精品2区 | 伊人婷婷综合 | 午夜精品一区二区三区在线播放 | 国产免费久久av | 日韩欧美高清在线 | 色九九在线 | 日韩欧美视频一区二区 | 人人澡av | 午夜精品久久久久久久久久久久久久 | 国产一级大片免费看 | 操操操天天操 | 国产精品麻豆99久久久久久 | 色五月成人 | 精品在线看 | 91久久久久久久一区二区 | 99re国产 | 亚洲欧美精品一区二区 | 国产毛片在线 | 黄视频网站大全 | 久久电影色 | 久久精品久久精品久久39 | 成人av电影免费 | 天天激情站 | 天堂网av在线 | 91中文在线| 伊人久久一区 | 中字幕视频在线永久在线观看免费 | 亚洲精品网站在线 | www..com黄色片 | 91网页版在线观看 | 免费黄色激情视频 | 超碰午夜| 午夜精品一二三区 | 香蕉日日 | 97人人模人人爽人人喊中文字 | 狠狠操天天射 | 天天夜操 | 久日精品 | 天天艹日日干 | 国产精品久久综合 | 色多多视频在线观看 | 成人羞羞视频在线观看免费 | 久久久久久久久久久久国产精品 | 色偷偷888欧美精品久久久 | 99色在线观看 | 久久精品国产第一区二区三区 | 亚洲va韩国va欧美va精四季 | 国产成人精品久久二区二区 | av手机版| 亚洲欧洲精品一区二区 | 久久人网| 色综合国产 | 综合久久影院 | 天天射天天爱天天干 | 日韩区欠美精品av视频 | 色播五月激情综合网 | 在线观看www. | 极品美女被弄高潮视频网站 | 欧美91片 | 九九有精品 | 97色狠狠 | 久久综合色一综合色88 | 网站在线观看日韩 | 96av麻豆蜜桃一区二区 | 91免费国产在线观看 | 伊人天天色 | 日韩av成人免费看 | 中文字幕在线视频一区 | 狠狠狠色丁香综合久久天下网 | 亚洲va天堂va欧美ⅴa在线 | 亚洲久草在线视频 | 日韩经典一区二区三区 | 日韩免费一区二区三区 | 九九九免费视频 | 日韩视频一区二区三区在线播放免费观看 | 国内丰满少妇猛烈精品播放 | 欧美一进一出抽搐大尺度视频 | 综合久久精品 | 国产免费av一区二区三区 | 精品一区二区电影 | 超级碰碰碰碰 | 玖草影院 | 色av婷婷| 久久久久久久久久免费视频 | 日本精品久久久久中文字幕5 | 日韩欧美xxx | 粉嫩av一区二区三区四区 | 91黄色影视 | 免费在线观看av不卡 | 日韩一区二区三区高清免费看看 | 精品国产乱码久久久久久三级人 | 国产精品成久久久久三级 | 亚洲精品色视频 | 免费看国产一级片 | 日韩精品无码一区二区三区 | 97成人啪啪网 | 精品国内自产拍在线观看视频 | 九九精品视频在线看 | 欧美一级艳片视频免费观看 | 色在线视频网 | 日本激情动作片免费看 | 天天操天天射天天 | 精品视频亚洲 | 国产福利电影网址 | 成人91在线观看 | 操操操日日 | 国产一级片免费观看 | 国产精品一区二区电影 | 国产不卡免费视频 | 91看片在线观看 | 97自拍超碰 | 欧美精品亚洲精品日韩精品 | 国产美女在线免费观看 | 成人免费中文字幕 | 午夜视频免费 | 亚洲免费国产 | 色99中文字幕 | 亚洲精品乱码久久久久久蜜桃欧美 | 日韩在线观看av | 国产成人av片 | 久久久国产视频 | 久久国产精品免费一区二区三区 | 国产精品免费观看在线 | 亚洲天天在线日亚洲洲精 | 亚洲乱码精品久久久久 | 特片网久久 | 日韩精品一区二区三区外面 | 午夜精品久久久久久久久久 | 免费国产亚洲视频 | 日韩精品久久中文字幕 | 天天射天天操天天色 | 国产在线1区 | 国产99久久久国产精品免费二区 | 日日夜夜精品视频天天综合网 | 婷婷在线播放 | 97人人射| 午夜av日韩 | 久久资源在线 | 四虎成人精品在永久免费 | 成人av免费在线播放 | 六月色婷婷 | 欧美色综合久久 | 毛片一级免费一级 | 日韩中文字幕国产 | 国产精品九九九九九 | 久久综合色播五月 | 果冻av在线 | 欧美巨大荫蒂茸毛毛人妖 | 中文字幕在线观看2018 | 日本精品中文字幕在线观看 | 97在线观看免费观看高清 | 五月亚洲 | 免费三及片 | 麻豆国产网站入口 | 国产福利精品在线观看 | 黄色在线看网站 | 久久这里只有精品视频首页 | 三级小视频在线观看 | 日韩免费在线网站 | 国产一区免费视频 | 97视频总站| 五月婷婷视频在线 | 国产午夜在线观看视频 | 久久久久免费网站 | 一区二区中文字幕在线 | 天天干天天操天天 | 亚洲精品中文字幕视频 | 久久亚洲婷婷 | 久久人人97超碰com | 国内99视频| 久久视频免费在线观看 | av电影在线观看完整版一区二区 | 国产成人精品女人久久久 | 人人干人人超 | 国产最新视频在线 | 99久久久久免费精品国产 | 亚洲一区二区麻豆 | 国产二区精品 | 天天色天天 | 伊人五月天av| 免费在线观看av | 亚洲午夜精品电影 | www.久草视频 | 91中文字幕在线视频 | 夜夜操网站 | 久久性生活片 | 91亚洲狠狠婷婷综合久久久 | 91av在线视频播放 | 国产福利在线不卡 | 国产精品国产三级国产aⅴ入口 | 亚洲黄网站 | 在线中文字幕电影 | 亚洲精品美女在线 | 久草9视频 | 一二区av | 久爱综合 | 中文字幕人成乱码在线观看 | 香蕉久久国产 | 九九九电影免费看 | 天天干天天操天天操 | 国产精品淫 | 人人插人人射 | 国产在线精品福利 | 性色av香蕉一区二区 | 久久天堂亚洲 | 亚洲精品视频大全 | 亚洲女同ⅹxx女同tv | 91精品久久久久久综合乱菊 | 国产精品18久久久久vr手机版特色 | 免费观看全黄做爰大片国产 | 日韩动漫免费观看高清完整版在线观看 | 999久久国精品免费观看网站 | 99r在线 | 亚洲人视频在线 | 91av视频导航 | 黄色小说免费在线观看 | 日本夜夜草视频网站 | 在线观看中文字幕 | 亚洲精品小区久久久久久 | 欧美精品在线观看免费 | 午夜精品久久久久久久久久久久久久 | 久久久久亚洲国产 | 日韩精品视频在线观看免费 | 国产一级h | 久草网视频在线观看 | 特级西西人体444是什么意思 | 亚洲国产最新 | 狠狠色丁香婷综合久久 | 日韩免费成人av | 中文字幕av免费 | 亚洲一区二区精品在线 | 中文字幕中文字幕在线中文字幕三区 | av在线免费观看不卡 | 国产v欧美 | 成年性视频 | 日日躁你夜夜躁你av蜜 | 久久人人爽人人人人片 | 亚洲一区二区三区在线看 | 色综合久久88色综合天天6 | 国产精品乱码久久久 | 91成人免费在线视频 | 亚洲国产精品久久久久久 | 91视视频在线直接观看在线看网页在线看 | 久久中文字幕导航 | 日韩天堂在线观看 | 亚洲成年人免费网站 | 九九九九色 | 国产日韩亚洲 | 在线日韩 | 亚洲一区av| 久久久久久久免费看 | 国产男女爽爽爽免费视频 | 久久久精品国产一区二区电影四季 | 国产中文字幕视频在线 | 国产精品麻豆91 | 久久伊人婷婷 | 国产免费一区二区三区最新 | av成人免费网站 | 久久精品第一页 | 免费欧美 | 久久精品99精品国产香蕉 | 日韩理论片在线观看 | 日本黄色免费看 | 天天噜天天色 | 日本视频高清 | 色婷婷激情网 | 9999在线| 国产高清免费在线观看 | 日韩美女久久 | 国产护士在线 | 国产精品毛片久久蜜 | 欧美有色 | 深夜激情影院 | 婷婷www| 久久久久久久影视 | 国内综合精品午夜久久资源 | 最新日韩视频在线观看 | 91在线视频 | 国产亚洲精品电影 | 97在线视 | 国产精品免费小视频 | 亚洲综合视频在线 | 国产婷婷一区二区 | 五月婷婷中文网 | 丁香五月亚洲综合在线 | 伊人网综合在线观看 | 丝袜网站在线观看 | 五月婷婷视频 | 三级动态视频在线观看 | 在线天堂8√ | 黄色免费在线视频 | 亚洲成人av片 | 成人一级在线 | 三级毛片视频 | 中文字幕一区二区三区乱码在线 | av久久在线 | 久久综合中文字幕 | 一本—道久久a久久精品蜜桃 | 久久久久亚洲精品中文字幕 | 中文字幕 婷婷 | 成人中文字幕+乱码+中文字幕 | 亚洲综合在线五月天 | 亚洲免费视频在线观看 | 成人av电影在线观看 | 日韩av福利在线 | 国产精品丝袜 | 国产精品不卡 | 狠狠躁日日躁夜夜躁av | 久久av黄色 | 国产一级二级在线播放 | 国产一线二线三线性视频 | 91精品国产成 | 免费观看成人网 | 中文字幕在线观看av | 亚洲人成综合 | 日韩有码中文字幕在线 | 国产精品一区二区在线 | 国产精品99久久久久 | 亚洲人人网| 91香蕉视频720p | 亚洲 av网站 | 久久人人爽人人爽人人片 | 亚洲天堂网在线视频观看 | 成人中文字幕av | 欧美成人日韩 | 五月婷婷在线播放 | 91免费网| 久久99在线观看 | 最新国产中文字幕 | 8x成人在线 | 国产精品免费一区二区 | 国产高清专区 | 国产高清视频免费最新在线 | 精品国产一区二区三区久久久 | 日韩一级黄色av | 狠狠色丁香婷婷综合久小说久 | 国产美女主播精品一区二区三区 | 热久在线 | 国产黄大片| 久久r精品 | 在线中文字幕一区二区 | 日本午夜免费福利视频 | 国产精品视频免费在线观看 | 色噜噜在线观看 | 日韩精品视频免费专区在线播放 | 亚洲视频精品在线 | 日韩久久精品一区二区三区下载 | 二区三区在线视频 | 亚洲天堂网视频在线观看 | 亚洲欧美日韩一二三区 | 日韩av影视在线观看 | 欧美成年网站 | 成人免费观看网站 | 麻豆免费视频 | 国产又粗又硬又爽的视频 | 久久人人爽人人爽人人片av免费 | 日本精油按摩3 | 成人黄视频 | 国产福利在线免费观看 | 麻豆高清免费国产一区 | 国产高清小视频 | 男女日麻批 | 黄污视频大全 | 色综合网在线 | 久久人网 | 欧美午夜精品久久久久久孕妇 | 91亚洲夫妻| 久久久国产精品亚洲一区 | 美女网站色在线观看 | 手机在线视频福利 | 精品欧美乱码久久久久久 | 狠狠夜夜 | 高清av中文在线字幕观看1 | 国产亚洲人成网站在线观看 | 日韩天天操 | 日韩毛片一区 | 99久精品视频| 在线观看视频中文字幕 | 久久久三级视频 | 丝袜美腿av| 香蕉久久久久久久 | 97在线看片 | 久久精品视频在线看 | 久久激情五月婷婷 | 这里只有精品视频在线 | 狠日日| 欧美最新大片在线看 | 久久综合操 | 天堂av免费看 | 在线va网站| 国产白浆视频 | 久久久精品免费看 | 黄色片网站 | 最近高清中文字幕在线国语5 | 亚洲精品视频在线播放 | 99热这里是精品 | 精品国产aⅴ麻豆 | 黄色小视频在线观看免费 | 97精品在线视频 | 玖玖在线看 | 婷婷六月色 | 久久久久蜜桃 | 日韩精品免费在线播放 | 久久综合九色综合网站 | 日韩精品三区四区 | 99综合电影在线视频 | 日韩在线视 | 成人黄色大片在线免费观看 | 精品成人久久 | 99在线观看视频 | 一级电影免费在线观看 | 欧美日韩国产免费视频 | 日韩欧美久久 | 日韩免费一区 | 亚洲国产成人精品在线观看 | 久久最新视频 | 国产精品国内免费一区二区三区 | 亚洲视频精品 | 黄色亚洲免费 | 黄色小说在线免费观看 | 久久综合九色九九 | 天天爱天天操 | 成人综合婷婷国产精品久久免费 | 亚洲va综合va国产va中文 | 麻豆视频在线免费看 | 色综合五月 | 韩日av在线| 国产一区麻豆 | 少妇bbb| 一区二区三区观看 | 九九精品在线观看 | 亚洲四虎在线 | 91热视频在线观看 | 亚洲成av人片 | 精品一区 在线 | 国产91精品一区二区麻豆亚洲 | 一区免费观看 | 国产尤物在线视频 | 国产裸体bbb视频 | 黄色片网站 | 久久久久久久免费看 | av在线免费网 | 国产视频网站在线观看 | 日韩欧美一区二区三区免费观看 | 92中文资源在线 | 五月天六月婷 | 人人爽人人澡人人添人人人人 | 五月婷婷视频 | 色视频网址 | 九九视频精品免费 | 91成人精品一区在线播放69 | 美女在线观看av | 欧美成年网站 | 日韩高清av在线 | 日韩av一区二区在线 | 亚洲综合五月天 | 免费a级观看 | 中文字幕国产一区二区 | 在线观看亚洲免费视频 | av成人在线看| 国产精品久久久久久久久费观看 | 免费看黄色大全 | 国产精品无 | 亚洲精品黄 | 国产美女精彩久久 | 深爱开心激情 | 91私密保健 | 日本99久久 | 奇米网777 | 国产成人久久av | 91chinese在线 | 日韩av三区 | 久草在线这里只有精品 | 九九热在线精品 | 99爱在线观看 | 96精品视频 | 一区二区三区四区五区在线 | 精品一区二区三区香蕉蜜桃 | 婷婷激情在线观看 | 亚洲乱码精品久久久久 |