婷婷五色,五月天激情婷婷大综合,亚洲综合久久久久久中文字幕,国产ww久久久久久久久久,婷婷综合缴情亚洲五月伊,欧美日韩不卡在线

首頁 > 生活 >

【Spring源碼】- 10 Spring AOP核心API

概述

Spring的兩大核心:IoCAOPIoC作為Spring的根基,通過大量的擴展點讓系統輕而易舉的就可以實現良好的擴展性,而AOPIoC結合在一起,類似于發生強大化學反應一樣,將Spring的功能性又提高了一個層次。Spring中也有大量使用AOP場景,比如@Configuration、數據庫事務、mybatis mapper接口注入等等。


(資料圖片)

AOP全稱Aspect Oriented Programming,即面向切面編程,其并非Spring獨有,作為一種對OOP編程思想的補充,其也有自己的標準規范并有獨立的組織進行維護。

根據織入時機的不同,AOP又可以分為三類:

編譯時織入:ApectJ主要采用的就是編譯時織入方式,這種一般使用特定的編譯器方式實現;類加載時織入:這種一般都是依賴JVM Instruments技術實現,Spring中也有對這種技術支持,具體可以了解下LoadTimeWeaver;動態織入:動態代理方式實現AOP就是動態織入場景,Spring中實現AOP最主要方式,根據動態代理方式不同,又可以分為:JDK動態代理CGLIB動態代理。

AOP標準規范是由獨立的組織機構進行維護,其涉及到的核心概念主要如下:

連接點(JoinPoint):程序運行中的某個階段點,比如方法的調用、異常的拋出、類初始化和對象實例化等。連接點是AOP的核心概念,并且定義了在應用程序中可以使用AOP插入其它邏輯的點;切點(Pointcut):切點是基于規則定義如何查找連接點,其可以看成包含一系列連接點的組合,Spring中對應的是Pointcut接口,定義了哪些類的哪些方法需要織入增強;通知(Advice):在連接點處需要織入的增強代碼邏輯封裝;切面(Aspect):切面是AdvicePointcut組合,對應SpringAdvisor;織入(Weaving):織入是在適當的位置將切面插入到應用程序代碼中的過程,就是上面說的編譯時織入、類加載時織入和動態織入;目標對象(target):AOP代理增強的原生對象;

基礎API

Spring AOP很多人不能很好的理解、使用,一方面是因為AOP涉及的概念可能比較抽象,不容易理解;另外一方面你對Spring AOP涉及到的一些基礎API不熟悉。下面我們就對Spring AOP中最核心的一些API,由底向上,由基礎到高級方式一步步分析。

Enhancer

Spring AOP主要使用的是動態代理方式實現,動態代理實現主要包括兩種:jdk動態代理cglib動態代理。jdk動態代理方式比較熟悉,下面就來看下cglib動態代理如何實現。

Spring中提供了一個工具類:Enhancer,Spring中主要就是利用該工具類創建cglib動態代理。下面我們通過一個案例看下其基本使用:

1、創建Callback回調接口類,該接口中就可以實現增強邏輯:

public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)   throws Throwable {  try {   before(method);//前置通知   Object ret = methodProxy.invokeSuper(obj, args);//目標方法執行   after(method, ret);//后置通知   return ret;  } catch (Exception e) {   exception();//異常通知  } finally {   afterReturning();//方法返回通知  }  return null; } //前置增強 private void before(Method method) {  System.out.printf("before execute:%s\r\n", method.getName()); } //后置增強 private void after(Method method, Object ret) {  System.out.printf("after execute:%s, ret:%s\r\n", method.getName(), ret); } //異常增強 private void exception() {  System.out.println("execute failure"); } //after返回增強 private void afterReturning() {  System.out.println("execute finish"); }    }

2、編寫測試:

//NoOp.INSTANCE:NoOp回調把對方法調用直接委派給這個方法在父類中的實現,即可理解為真實對象直接調用方法,沒有任何增強private static final Callback[] CALLBACKS = new Callback[] {            new MyMethodInterceptor(),            NoOp.INSTANCE};public void test()  {    //創建Enhancer實例    Enhancer enhancer =  new Enhancer();        //cglib是基于繼承方式代理,superClass就是基于哪個類型父類進行增強,創建出來的對象就是該類型子類    enhancer.setSuperclass(UserServiceImpl.class);    //CallbackFilter主要用于過濾不同Method使用不同的Callback    enhancer.setCallbackFilter(new CallbackFilter() {        @Override        public int accept(Method method) {            if (method.getDeclaringClass() == Object.class) {                return 1;//使用Callback數組下標是1的            }            return 0;//使用Callback數組下標是0的        }    });    //設置Callback數組,Callback就是封裝的增強邏輯    enhancer.setCallbacks(CALLBACKS);    //創建代理對象    UserService proxyObj = (UserService) enhancer.create();    System.out.println(proxyObj.say("zhangsan"));}

通過上面enhancer.create()這條語句,就可以為目標類創建一個cglib動態代理,通過Callback回調方式將各種增強邏輯織入到代理實例中。

還可以使用Enhancer.createClass()方法只創建出代理類型,然后自己通過反射方式創建對象。這時,需要注意:1、這時就不能使用setCallbacks()設置Callback數組,而是使用setCallbackTypes()設置Callback對應的類型;2、Enhancer.createClass()執行完成后,再通過Enhancer.registerStaticCallbacks(clz, CALLBACKS)方式設置Callback數組;

enhancer.setInterfaces()可用于設置生成的代理類必須實現的接口,比如你可以不設置superclass,只設置interfaces,這時也是可以正常創建出基于這個接口的動態代理實例,但是這時就要注意不能觸發目標對象方法執行,如methodProxy.invokeSuper執行會報錯,如下:

public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)  throws Throwable { try {  before(method);//前置通知  //Object ret = methodProxy.invokeSuper(obj, args);//目標方法執行  after(method, ret);//后置通知  return ret; } catch (Exception e) {  exception();//異常通知 } finally {  afterReturning();//方法返回通知 } return null;}

基于接口創建的代理實例還是非常有用的,比如mybatis mapper就是一個沒有實現類的接口,但是在spring中卻可以依賴注入到service bean中,其中就是利用到上面基于接口創建動態代理的思想,注入進來的其實就是基于接口的動態代理,然后調用接口中方法時就可以進行攔截,獲取到具體調用方法簽名信息以及參數信息,基于這些數據進行業務邏輯處理。

invoke和invokeSuper方法區別

Callback#intercept()回調方法中執行methodProxy.invokeSuper()methodProxy.invoke()是有很大區別的,而且看不到執行流程,所以這里涉及的邏輯非常繞。

public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)  throws Throwable { Object ret = methodProxy.invokeSuper(obj, args);    Object ret = methodProxy.invoke(delete, args);}

大致區別如下圖:

客戶端觸發代理對象say方法調用,首先進入代理對象中的同名方法,然后進入方法攔截對象MethodInterceptor,這里會出現兩種情況:

如果調用invokeSuper方法,流程會重新走到代理對象中,代理對象這時會識別出是調用super中同名方法,所以沒有繼續向下走,而是通過super.say()方式調用目標對象中的方法。如果調用invoke方法,代理對象內部其實包裹一個目標對象target,這時它是直接通過target.say方式調用目標對象。

invokeSuper()invoke()方法都可以調用到目標對象方法,但是它們之間存在的一個本質區別:上下文環境不一樣;或者更直接說:目標對象中this指向不一樣。通過super.say()方式調用的目標對象,this指向的是代理對象;而通過target.say()方式調用的,目標對象中this指向的就是目標對象本身。這會導致什么差異呢?

假如目標對象類型如下定義,然后使用Enhancer創建一個代理對象:

public class Target {        public void a() {        System.out.println(" a 方法");        b();    }        public void b() {        System.out.println(" b 方法");    }}

客戶端觸發代理對象a()方法執行,如果攔截器中使用invoke方式調用目標對象:直接調用目標對象a()方法,這個方法中又會通過this.b()調用方法b,由于是目標對象本身內部調用,所以b()方法不會被攔截的。

客戶端觸發代理對象a()方法執行,如果攔截器中使用invokeSuper()方式調用目標對象:這里是通過super.a()方式調用目標對象中的a()方法,然后a()方法又會通過this.b()調用方法b,注意這時的this不是目標對象本身,而是代理對象,因為代理對象繼承目標對象,代理對象會有重名方法覆寫了目標對象方法。所以,this.b()實際上會觸發代理對象中方法b的執行,這時是會觸發攔截器的。

所以,methodProxy.invokeSuper(obj, args)這個obj是代理對象;而methodProxy.invoke(obj, args)這個入參obj是目標對象。搞清楚這些基本理解清楚應該使用invoke還是invokeSuper。

ProxyFactory

Enhancer只能用于創建cglib動態代理,Spring中還有一個更上層點的類ProxyFactory,可以用于創建JDK動態代理cglib動態代理。

public void test02() { ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTarget(new UserServiceImpl());    /*    調用ProxyFactory.addInterface()或setInterfaces()表示對接口進行代理,一般會使用jdk動態代理,    除非setOptimize(true)或setProxyTargetClass(true)表示使用cglib代理    cglib代理類名稱格式大致為:ServiceImpl$$EnhancerBySpringCGLIB$$f2952b94    */ //setInterfaces設置這個,會基于接口代理,使用jdk動態代理方式 proxyFactory.setInterfaces(UserService.class); //proxyFactory.setOptimize(true); //proxyTargetClass=true:直接代理目標類,而不是接口,使用cglib proxyFactory.setProxyTargetClass(true); // 添加增強 proxyFactory.addAdvice(new MyBeforeAdvice02());    //內部使用了緩存,target不變時,getProxy()獲取到的都是同一個    //只有target變化時,才會重新創建新的代理對象 Object proxy = proxyFactory.getProxy();}

ProxyFactory類是AOP底層實現中非常重要的一個類,另外AnnotationAwareAspectJAutoProxyCreatorBeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator等一些高級AOP實現工具類都是通過在其父類AbstractAutoProxyCreator中借助ProxyFactory實現AOP邏輯織入的。所以,理解ProxyFactory的使用對理解Spring AOP至關重要。

ProxyFactory類控制代理的創建過程,其內部委托給DefaultAopProxyFactory的一個實例,該實例又轉而委托給Cglib2AopProxyJdkDynamicAopProxy,用于創建基于cglib代理還是jdk代理,想了解這兩種動態代理區別可以分析下這個類源碼。

ProxyFactoryaddAdvice()方法將傳入的通知封裝到DefaultPointcutAdvisor(DefaultPointcutAdvisorPointcutAdvisor的標準實現)的一個實例中,并使用默認包含所有方法的切入點對其進行配置。為更加靈活細粒度的控制在哪些連接點上攔截通知,可以使用addAdVisor()方法添加一個帶有切入點消息的Advisor

可以使用相同的ProxyFactory實例來創建多個代理,每個代理都有不同的切面。為了幫助實現該過程,ProxyFactory提供了removeAdvice()removeAdvisor()方法,這些方法允許從ProxyFactory中刪除之前傳入的任何通知或切面,同時可以使用boolean adviceIncluded(@Nullable Advice advice)檢查ProxyFactory是否附有特定的通知對象。

Advice

ProxyFactoryaddAdvice()addAdvisor()兩個方法分別引入了兩個重要的類:AdviceAdvisor。首先,我們來看下Advice這個接口類,其可以看成需要織入增強的代碼邏輯封裝。AdviceSpringAPI結構如下:

大致描述:

BeforeAdvice:前置通知,該接口沒有任何方法,平時主要使用其子類MethodBeforeAdvice,因為Spring中只能在方法前后織入,對應注解@Before;AfterAdvice:后置通知,其存在兩個子類AfterReturningAdviceThrowsAdvice,分別對應@AfterReturning@AfterThrowing;MethodInterceptor:可以實現環繞通知,對應注解@Around;

Advisor

AOP規范中有切面概念,在Spring中大概對應就是Advisor。Advisor有兩個子接口:PointcutAdvisorIntroductionAdvisor

其實真正使用比較多的是它的子類PointcutAdvisor,該接口關鍵就是如下兩個方法:

public interface PointcutAdvisor { Advice getAdvice(); Pointcut getPointcut();}

PointcutAdvisor從接口定義大概就可以看出,其就是對AdvicePointcut的封裝,Advice代表的是橫切面需要織入的代碼,而Pointcut定義了如何去切的問題。從之前分析來看,Advice也可以看出一種非常簡單的切面,是對指定的類所有方法都進行切入,橫切面太寬泛,靈活性不夠,PointAdvisor引入了Pointcut后顯然比Advice更加靈活、強大。

PointcutAdvisor主要有6個具體的實現類,分別介紹如下:

DefaultPointcutAdvisor:最常用的切面類型,它可以通過任意PointcutAdvice定義一個切面,一般可以通過擴展該類實現自定義的切面;NameMatchMethodPointcutAdvisor:通過該類可以定義按方法名定義切點的切面;RegexpMethodPointcutAdvisor:使用正則表達式模式定義切點,其內部通過JdkRegexpMethodPointcut構造出正則表達式方法名切點;StaticMethodMatcherPointcutAdvisor:靜態方法匹配器切點定義的切面,默認情況下,匹配所有的目標類;AspecJExpressionPointcutAdvisor:用于Aspecj切點表達式定義切點的切面;AspecJPointcutAdvisor:用于AspecJ語法定義切點的切面;

其實,這些Advisor主要區別還是基于其內部封裝的Pointcut實現類體現的,在實際工作中這些類使用的可能不多,這里的核心在于Pointcut如何定義切入點,所以實際開發中更多的可能會去定制Pointcut實現類,然后使用DefaultPointcutAdvisor將其包裝成Advisor使用。

下面通過RegexpMethodPointcutAdvisor案例簡單了解即可:

public void test1(){    AnnotationConfigApplicationContext context =            new AnnotationConfigApplicationContext("aop.demo03");    UserServiceImpl target = new UserServiceImpl();    ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();    proxyFactoryBean.setTarget(target);    proxyFactoryBean.setProxyTargetClass(true);    RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor();    //設置advisor的advice    advisor.setAdvice(new MyBeforeAdvice02());    //設置advisor的pointcut,aop.demo03包下所有類中已say開頭的方法才會織入    advisor.setPattern("aop.demo03..*.say*");    proxyFactoryBean.addAdvisor(advisor);    proxyFactoryBean.setBeanFactory(context);    Object obj = proxyFactoryBean.getObject();    System.out.println(obj.getClass().getName());    UserServiceImpl userService = (UserServiceImpl) obj;    System.out.println(userService.say("haha"));}

RegexpMethodPointcutAdvisor表示通過正則表達式進行切點描述的切面,它有一個pattern屬性用來指定增強要應用到哪些類的哪些方法,也可以通過patterns屬性指定多個表達式進行匹配。有一個advice屬性用來表示要應用的增強,這樣就能表示一個完整的切面了。

Pointcut

Advisor引入了一個核心接口Pointcut,其描述了對哪些類的哪些方法進行切入。Pointcut從其定義可以看出其由ClassFilterMethodMatcher構成。ClassFilter用于定位哪些類可以進行切入,然后再通過MethodMatcher定位類上的哪些方法可以進行切入,這樣Pointcut就擁有了識別哪些類的哪些方法能被進行切入的能力。

public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher();}

Pointcut接口API結構見下:

其中這里比較常用的AnnotationMatchingPointcut基于注解進行切入,之前分析【Spring源碼】- 09 擴展點之@Import注解一節就使用到該實現類,將標記有@MyAsync注解的方法都進行增強就是利用這個實現類:

AnnotationMatchingPointcut pointcut = AnnotationMatchingPointcut.forMethodAnnotation(MyAsync.class);Advice advice = new AsyncAnnotationAdvice(executor);DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();advisor.setPointcut(pointcut);advisor.setAdvice(advice);ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(bean);if(!this.isProxyTargetClass()){ proxyFactory.setInterfaces(bean.getClass().getInterfaces());}proxyFactory.addAdvisor(advisor);proxyFactory.copyFrom(this);return proxyFactory.getProxy();

ProxyFactoryBean

ProxyFactoryBeanProxyFactory功能和使用其實差不多,底層邏輯也基本一致,ProxyFactoryBean主要是融合了IOC功能。一方面ProxyFactoryBean類是FactoryBean的一個實現,更加方便注入IoC中,參照mybatisspring整合一節,其中關鍵一步就是將掃描的BeanDefinitionbeanClass由接口類替換成FactoryBean類型;另一點就是切面可以使用IoC容器bean。

下面通過一個案例簡單看下ProxyFactoryBean使用:

package org.simon.ioc.demo1;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Componentpublic class MyBeforeAdvice implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {  System.out.println("-----洗手-----"); }}
@Testpublic void test1(){ AnnotationConfigApplicationContext context =    new AnnotationConfigApplicationContext("org.simon.ioc.demo1"); UserService target = new UserServiceImpl(); ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); proxyFactoryBean.setTarget(target); proxyFactoryBean.setInterceptorNames("myBeforeAdvice", "otherAdvice*"); proxyFactoryBean.setBeanFactory(context); Object obj = proxyFactoryBean.getObject(); System.out.println(obj.getClass().getName()); UserService userService = (UserService) obj; System.out.println(userService.say("haha"));}

其中關鍵一步在:proxyFactoryBean.setInterceptorNames("myBeforeAdvice", "otherAdvice*");,可以使用IoC中的beanName,同時還支持通配符*IoC中查找對應Bean。

高級API

前面介紹的類、接口等都是Spring AOP中一些底層API,使用起來不太方便,感覺功能不太強大,不論是ProxyFactory還是ProxyFactoryBean創建織入切面的代理,每次只能硬編碼一個具體的Bean,假如我想將某個包路徑下符合一定規則的類的特定方法都進行織入代理怎么辦?

使用前面那些API好像都不能實現這個需求,但是結合之前分析的Spring擴展點,很容易想到可以結合BeanPostProcessor擴展點實現這個需求,postProcessAfterInitialization()這個方法回調時Bean依賴注入、初始化等都已經完成,這時就可以在這個方法中過濾出符合一定條件的Bean進行代理增強處理。

其實,在Spring中基于這種思想,已經為我們提供了三個實現類:

BeanNameAutoProxyCreator:基于beanName進行織入增強,通過setBeanNames(String... beanNames)將需要增強的beanName設置進去;DefaultAdvisorAutoProxyCreator:基于Advisor匹配機制進行織入增強,它會對容器中所有的Advisor進行掃描,自動將這些切面應用到匹配的Bean中;AnnotationAwareAspectjAutoProxyCreator:基于BeanAspectJ注解方式進行織入增強,就是實現平時使用的@Aspect、@Before、@AroundAspectJ注解功能支持。

下面我們就來通過DefaultAdvisorAutoProxyCreator了解下使用場景:

1、定義一個目標類,后續就是基于該類進行增強:

@Componentpublic class UserServiceImpl{ public String say(String name){  System.out.println("執行:==UserService#say===");  return "hello,"+name; }}

2、定義一個配置類:

@Configuration@ComponentScan(basePackageClasses = AopConfig.class)public class AopConfig {    @Bean    public RegexpMethodPointcutAdvisor regexpMethodPointcutAdvisor(){        RegexpMethodPointcutAdvisor advisor = new RegexpMethodPointcutAdvisor();        advisor.setAdvice(new MyBeforeAdvice02());        //aop.demo03包下所有類中帶有say開頭方法進行增強        advisor.setPattern("aop.demo03..*.say*");        return advisor;    }    @Bean    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){        return new DefaultAdvisorAutoProxyCreator();    }}

這個類有兩個關鍵,一個是向IoC中注入Advisor,之前分析過Advisor包含兩個功能:

通過Pointcut定位哪些類的哪些方法需求切入;通過關聯的Advice指定切入增強邏輯;

另一個關鍵就是注入DefaultAdvisorAutoProxyCreator,這個就是一個Spring內置的實現BeanPostProcessor擴展類,其在postProcessAfterInitialization()方法中對Bean進行切入增強。

3、測試:

public void test1(){        AnnotationConfigApplicationContext context =                new AnnotationConfigApplicationContext(AopConfig.class);        System.out.println(context.getBean(UserServiceImpl.class).getClass());}

context.getBean(UserServiceImpl.class)IoC容器中獲取的就是使用cglib代理后的實例。

下面我們再來分析下AnnotationAwareAspectjAutoProxyCreator,平時如果項目中需要開啟AOP功能,使用@EnableAspectJAutoProxy注解方式開啟,我們來看下該注解干了什么?

1、@EnableAspectJAutoProxy注解使用@Import注解將AspectJAutoProxyRegistrar引入:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(AspectJAutoProxyRegistrar.class)public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false;}

2、AspectJAutoProxyRegistrarImportBeanDefinitionRegistrar接口實現類:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(   AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {  //注冊一個SmartInstantiationAwareBeanPostProcessor類型的實現類:AnnotationAwareAspectJAutoProxyCreator  AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);  AnnotationAttributes enableAspectJAutoProxy =    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);  if (enableAspectJAutoProxy != null) {   if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);   }   if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);   }  } }}

其中最關鍵一句AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);,就是向IoC容器中注入AnnotationAwareAspectJAutoProxyCreator。

這樣我們就明白了@EnableAspectJAutoProxy注解方式開啟AOP的本質就像向IoC中注入AnnotationAwareAspectJAutoProxyCreator,它利用BeanPostProcessor擴展點功能實現織入增強邏輯。

總結

首先,對Spring AOP底層一些最基礎、最核心的API的分析梳理,相信你會對Spring AOP底層實現邏輯有了一個更加深入的理解。然后通過Spring AOP提供的高級API,理解了如何將IoCAOP集成到一起實現強大功能,對SpringAOP的整體實現思路也有了比較清晰的認識。

關鍵詞:

責任編輯:Rex_28

推薦閱讀

為鄉村振興注入體育動力

· 2023-03-28 11:32:28

工行可轉債_工行融e借

· 2023-03-28 11:22:17

關于我們 聯系我們 商務合作 誠聘英才 網站地圖

Copyright @ 2008-2020 www.miyueyun.com.cn Corporation,All Rights Reserved

熱訊新聞網 版權所有 備案號:豫ICP備20005723號-6
文章投訴郵箱:2 9 5 9 1 1 5 7 8@qq.com 違法信息舉報郵箱:jubao@123777.net.cn

營業執照公示信息

老熟妇毛茸茸BBW视频| 国产无套码AⅤ在线观看在线播放 国产无套码AⅤ在线观看 | 丝袜AV在线丝袜AV天堂| 国产精品亚洲一区二区三区| 亚洲色在线无码国产精品不卡| 欧美VIDEOS另类色HDFR| 国产MV高清砖码2022| 亚洲国产最大AV| 欧美大屁股XXXⅩOOOO| 国产99在线 | 欧美| 亚洲鲁丝片AV无码多人| 欧美高清视频手机在在线| 国产成人午夜精品一区二区三区| 亚洲精品无码久久毛片| 欧美精产国品一二三产品工艺| 国产成人无码精品一区二区三区| 亚洲日本人成网站在线播放| 欧美做受三级级视频播放| 国产精品久久久久精品综合紧| 亚洲日韩欧洲乱码AV夜夜摸| 青青草原综合久久大伊人精品| 国产精品亚洲А∨天堂免| 亚洲最大的AV无码网站| 日产精品一二三区| 极品婬荡少妇XXXX欧美| CHINESE性内射高清国产| 无遮挡又黄又刺激的视频| 旧芭乐视频官网下载地址IOS| 成人区精品人妻人妻AV| 亚洲国产精品成人午夜在线观看| 欧美极品性饥渴少妇大战黑人| 国产精东天美AV影业传媒| 野花香HD免费高清版6高清版| 日本大学SGU大二大三| 娇妻卧室含辱迎接领导是哪部电影 | 无人区卡一卡二卡三乱码入口 | 亚洲国产成人精品无码区在线观看 | 中文字幕丰满伦子无码| 中文字幕久久精品波多野结百度 | 色窝窝无码一区二区三区成人网站| 久久水蜜桃网国产欧美H版护士| 国产精品成人3p一区二区三区| 99久9在线 | 免费| 亚洲欧美成人AⅤ在线专区| 色综合色狠狠天天综合网| 男阳茎进女阳道啪啪| 禁止18点击进入在线观看尤物| 给个网站2021年直接进入的| 3D动漫同人精品无码专区| 亚洲加勒比无码一区二区| 熟妇人妻av无码一区二区三区 | 人妻 丝袜美腿 中文字幕| 久久久久久久女国产乱让韩| 国产拍揄自揄免费观看| 成人全部免费的A毛片在线看| 中文成人无字幕乱码精品区| 亚洲国产精品久久久久久久蜜桃 | 在线观看亚洲AV日韩A∨| 亚洲AV无码专区亚洲AV| 少妇与子乱A级全毛片| 欧美极品少妇XXXX亚洲精品| 久久九九兔免费精品6| 国产无遮挡裸露视频免费| 肥水不流外人田小说| CHINESEXXXXHD麻豆| 又爽又高潮的BB视频免费看| 亚洲AV永久无码精品无码自慰 | 国内精品国内精品自线在拍| 高清国产亚洲精品自在久久| JAPAN丰满人妻HDXXXX| 岳胀耸的雪乳奶水| 亚洲老熟女XXXXHDWAA| 小妖精又紧又湿高潮H视频69| 色综合天天综合网国产| 啪啪男女爱高潮GIF| 蜜臀AV一区二区三区四区| 久爱WWW成人网免费视频| 国产香蕉国产精品偷在线| 俄罗斯性孕妇孕交| 凹凸人妻人人澡人人添| 777成了乱人视频| 又黄又硬又湿又刺激视频免费| 亚洲精品国产综合久久一线| 亚洲A∨无码男人的天堂| 天堂AⅤ大芭蕉伊人AV| 日韩精品免费无码专区| 欧洲熟妇色XXXXⅩ欧洲老妇色| 免费国产成人高清在线视频| 久久久久久久精品国产免费… | 国产一区二区三区日韩精品| 国产成人综合欧美精品久久 | 波多野结衣片全部电影| AV无码AV高潮AV喷吹免费| 中文亚洲AV片在线观看不卡| 野花社区免费观看高清在线1日本 野花社区韩国视频WWW了 | 精品国产三级A∨在线无码| 国产无套内射又大又猛又粗又爽 | 久久精品无码一区二区日韩AV| 国语自产第1国语自产第10页| 国产精品偷窥老熟女高潮| 国产99视频精品免费视频6| 成人午夜视频精品一区| 吧唧吧唧吧唧一口一口吃掉了 | 亚洲AV无码一区二区三区天堂古| 无码人妻久久一区二区三区免费丨 | 无码国产精品一区二区免费模式 | 做AJ的视频大全电视剧| 在线成人精品国产区免费| 野花社区WWW在线视频官网| 亚洲深深色噜噜狠狠网站| 亚洲欧美偷拍另类A∨| 亚洲成AV人片在线观看无APP| 亚洲AV网站在线观看| 亚洲 精品 综合 精品 自拍| 五十熟妇日本熟妇久久| 午夜精品久久久久久久无码| 午夜免费福利小电影| 性色AV免费网站| 亚洲AV成人无码网天堂| 亚洲AV日韩AV蜜桃在线播放| 亚洲AV日韩AV无码AV一区二| 亚洲AV片不卡无码潮| 亚洲AV无码兔费综合在线观看| 亚洲AV无码乱码忘忧草亚洲人| 亚洲AV高清在线观看一区二区| 亚洲AV成人一区国产精品小说| 亚洲AV福利院在线观看| 亚洲AV无码专区在线电影成人| 亚洲AV中文无码乱人伦在线r▽| 亚洲VA在线VA天堂VA不卡| 亚洲爆乳WWW无码专区| 亚洲精品乱码久久久久久蜜桃不卡 | 亚洲AV片不卡无码一| 亚洲AV永久无码成人网站| 亚洲成色WWW久久网站| 亚洲精品无码久久久久APP| 亚洲欧美另类激情综合区蜜芽| 亚洲欧洲∨国产一区二区三区| 亚洲中文久久久久久精品| 伊人婷婷六月狠狠狠去| 中文字幕人妻偷伦在线视频| 2019四虎影视最新在线| 99久久精品费精品国产| VODAFONEWIFI性另类| 成 人 黄 色 网站 S色| 多肉到处做的古文| 国产极品视觉盛宴专区| 国产在线观看精品一区二区三区| 好爽又高潮了毛片| 久久99久久99精品免观看吃奶| 久久夜色精品国产亚洲AV| 免费人成视频网站在线18| 欧美人妻久久精品| 人妻中文字幕制服丝袜| 少妇BBW搡BBBB搡BBBB| 无码人妻丰满熟妇区毛片18| 亚洲AV无码潮喷在线入口| 亚洲欧美精品视频| 在教室伦流澡到高潮HGL动漫 | 中国内射XXXX6981少妇| AV无码久久久久不卡网站蜜桃 | 国99精品无码一区二区三区| 国产精品无码一区二区三区不卡| 国精产品一区一区三区有限在线| 精品熟妇无码av免费久久| 久久夜色精品国产噜噜| 欧美ZC0O人与善交| 日韩A∨精品日韩在线观看| 乌克兰美女的小嫩BBB| 亚洲AV永久无码老湿机男人网| 亚洲愉拍自拍欧美精品APP| 最新版天堂中文在线官网| 啊灬啊灬啊灬快灬高潮了听书 | 无码AV最新高清无码专区| 亚洲AV永久无码精品网址| 亚洲综合日韩久久成人AV| 99久久久国产精品免费蜜臀| 成人无码专区免费播放三区| 国产精品白丝JK白祙喷水视频| 娇小萝被两个黑人用半米长| 乱人伦中文字幕在线| 男女猛烈无遮挡免费视频| 国产AV精品白浆一区二| 国产午夜精品一区二区三区软件| 狠狠色噜噜狠狠狠狠AV不卡| 久久亚洲精品成人无码| 欧美熟妇精品一区二区蜜桃视频| 上到少妇叫爽TUBE| 亚洲AV成人一区二区三区不卡| 中文弹幕日产无线码一区| 无码国产精品一区二区免费VR| 亚洲AV无码一区二区少妇| 荫蒂添的好舒服视频囗交| www.av在线播放| 国产精东天美AV影业传媒| 精品久久伊人99热超碰| 粗大挺进尤物人妻| 国产精品亚洲片在线| 久久久久99精品成人片牛牛影视| 欧美精品一区二区三区人妻久久久|