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

Spring AOP 中的代理對象是怎么創建出來的?

開發 前端
首先實例化就是通過反射,先把 Bean 的實例創建出來;接下來屬性賦值就是給創建出來的 Bean 的各個屬性賦值;接下來的初始化就是給 Bean 應用上各種需要的后置處理器;最后則是銷毀。

1. AOP 用法

先來一個簡單的案例,小伙伴們先回顧一下 AOP,假設我有如下類:

@Service
public class UserService {

    public void hello() {
        System.out.println("hello javaboy");
    }
}

然后我寫一個切面,攔截 UserService 中的方法:

@Component
@Aspect
@EnableAspectJAutoProxy
public class LogAspect {

    @Before("execution(* org.javaboy.bean.aop.UserService.*(..))")
    public void before(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println(name+" 方法開始執行了...");
    }
}

最后,我們看一下從 Spring 容器中獲取到的 UserService 對象:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");
UserService us = ctx.getBean(UserService.class);
System.out.println("us.getClass() = " + us.getClass());

打印結果如下:

圖片圖片

可以看到,獲取到的 UserService 是一個代理對象。

其他各種類型的通知我這里就不說了,不熟悉的小伙伴可以在公眾號【江南一點雨】后臺回復 ssm,有松哥錄制的免費入門視頻。

2. 原理分析

那么注入到 Spring 容器中的 UserService,為什么在獲取的時候變成了一個代理對象,而不是原本的 UserService 了呢?

整體上來說,我們可以將 Spring Bean 的生命周期分為四個階段,分別是:

實例化。

屬性賦值。

初始化。

銷毀。

如下圖:

圖片圖片

首先實例化就是通過反射,先把 Bean 的實例創建出來;接下來屬性賦值就是給創建出來的 Bean 的各個屬性賦值;接下來的初始化就是給 Bean 應用上各種需要的后置處理器;最后則是銷毀。

2.1 doCreateBean

AOP 代理對象的創建是在初始化這個過程中完成的,所以今天我們就從初始化這里開始看起。

AbstractAutowireCapableBeanFactory#doCreateBean:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  throws BeanCreationException {
    //...
 try {
  populateBean(beanName, mbd, instanceWrapper);
  exposedObject = initializeBean(beanName, exposedObject, mbd);
 }
 //...
 return exposedObject;
}

小伙伴們看到,這里有一個 initializeBean 方法,在這個方法中會對 Bean 執行各種后置處理器:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
 invokeAwareMethods(beanName, bean);
 Object wrappedBean = bean;
 if (mbd == null || !mbd.isSynthetic()) {
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 }
 try {
  invokeInitMethods(beanName, wrappedBean, mbd);
 }
 catch (Throwable ex) {
  throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
 }
 if (mbd == null || !mbd.isSynthetic()) {
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }
 return wrappedBean;
}

這里一共是執行了四個方法,也都是非常常見的 Bean 初始化方法:

  1. invokeAwareMethods:執行 Aware 接口下的 Bean。
  2. applyBeanPostProcessorsBeforeInitialization:執行 BeanPostProcessor 中的前置方法。
  3. invokeInitMethods:執行 Bean 的初始化方法 init。
  4. applyBeanPostProcessorsAfterInitialization:執行 BeanPostProcessor 中的后置方法。

1、3 這兩個方法很明顯跟 AOP 關系不大,我們自己平時創建的 AOP 對象基本上都是在 applyBeanPostProcessorsAfterInitialization 中進行處理的,我們來看下這個方法:

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  throws BeansException {
 Object result = existingBean;
 for (BeanPostProcessor processor : getBeanPostProcessors()) {
  Object current = processor.postProcessAfterInitialization(result, beanName);
  if (current == null) {
   return result;
  }
  result = current;
 }
 return result;
}

小伙伴們看到,這里就是遍歷各種 BeanPostProcessor,并執行其 postProcessAfterInitialization 方法,將執行結果賦值給 result 并返回。

2.2 postProcessAfterInitialization

BeanPostProcessor 有一個實現類 AbstractAutoProxyCreator,在 AbstractAutoProxyCreator 的 postProcessAfterInitialization 方法中,進行了 AOP 的處理:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
 if (bean != null) {
  Object cacheKey = getCacheKey(bean.getClass(), beanName);
  if (this.earlyProxyReferences.remove(cacheKey) != bean) {
   return wrapIfNecessary(bean, beanName, cacheKey);
  }
 }
 return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  return bean;
 }
 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  return bean;
 }
 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  this.advisedBeans.put(cacheKey, Boolean.FALSE);
  return bean;
 }
 // Create proxy if we have advice.
 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
 if (specificInterceptors != DO_NOT_PROXY) {
  this.advisedBeans.put(cacheKey, Boolean.TRUE);
  Object proxy = createProxy(
    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  this.proxyTypes.put(cacheKey, proxy.getClass());
  return proxy;
 }
 this.advisedBeans.put(cacheKey, Boolean.FALSE);
 return bean;
}

可以看到,首先會嘗試去緩存中獲取代理對象,如果緩存中沒有的話,則會調用 wrapIfNecessary 方法進行 AOP 的創建。

正常來說,普通 AOP 的創建,前面三個 if 的條件都是不滿足的。第一個 if 是說 beanName 是否是一個 targetSource,顯然我們這里不是;第二個 if 是說這個 Bean 是不是不需代理(結合上篇文章一起理解),我們這里顯然是需要代理的;第三個 if 的作用我們也在上篇文章中和小伙伴們介紹過,這里就不再贅述了。

關于第二個 if 我多說一句,如果這里進來的是一個切面的 Bean,例如第一小節中的 LogAspect,這種 Bean 顯然是不需要代理的,所以會在第二個方法中直接返回,如果是其他普通的 Bean,則第二個 if 并不會進來。

所在在 wrapIfNecessary 中,最重要的方法實際上就是兩個:getAdvicesAndAdvisorsForBean 和 createProxy,前者用來找出來所有跟當前類匹配的切面,后者則用來創建代理對象。

2.3 getAdvicesAndAdvisorsForBean

這個方法,說白了,就是查找各種 Advice(通知/增強) 和 Advisor(切面)。來看下到底怎么找的:

AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean:

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
  Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
 if (advisors.isEmpty()) {
  return DO_NOT_PROXY;
 }
 return advisors.toArray();
}

從這里可看到,這個方法主要就是調用 findEligibleAdvisors 去獲取到所有的切面,繼續:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
 List<Advisor> candidateAdvisors = findCandidateAdvisors();
 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
 extendAdvisors(eligibleAdvisors);
 if (!eligibleAdvisors.isEmpty()) {
  eligibleAdvisors = sortAdvisors(eligibleAdvisors);
 }
 return eligibleAdvisors;
}

這里一共有三個主要方法:

  • findCandidateAdvisors:這個方法是查詢到所有候選的 Advisor,說白了,就是把項目啟動時注冊到 Spring 容器中所有切面都找到,由于一個 Aspect 中可能存在多個 Advice,每個 Advice 最終都能封裝為一個 Advisor,所以在具體查找過程中,找到 Aspect Bean 之后,還需要遍歷 Bean 中的方法。
  • findAdvisorsThatCanApply:這個方法主要是從上個方法找到的所有切面中,根據切點過濾出來能夠應用到當前 Bean 的切面。
  • extendAdvisors:這個是添加一個 DefaultPointcutAdvisor 切面進來,這個切面使用的 Advice 是 ExposeInvocationInterceptor,ExposeInvocationInterceptor 的作用是用于暴露  MethodInvocation 對象到 ThreadLocal 中,如果其他地方需要使用當前的 MethodInvocation 對象,直接通過調用 currentInvocation 方法取出即可。

接下來我們就來看一下這三個方法的具體實現。

2.3.1 findCandidateAdvisors

AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

@Override
protected List<Advisor> findCandidateAdvisors() {
 List<Advisor> advisors = super.findCandidateAdvisors();
 if (this.aspectJAdvisorsBuilder != null) {
  advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
 }
 return advisors;
}

這個方法的關鍵在于通過 buildAspectJAdvisors 構建出所有的切面,這個方法有點復雜:

public List<Advisor> buildAspectJAdvisors() {
 List<String> aspectNames = this.aspectBeanNames;
 if (aspectNames == null) {
  synchronized (this) {
   aspectNames = this.aspectBeanNames;
   if (aspectNames == null) {
    List<Advisor> advisors = new ArrayList<>();
    aspectNames = new ArrayList<>();
    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      this.beanFactory, Object.class, true, false);
    for (String beanName : beanNames) {
     if (!isEligibleBean(beanName)) {
      continue;
     }
     // We must be careful not to instantiate beans eagerly as in this case they
     // would be cached by the Spring container but would not have been weaved.
     Class<?> beanType = this.beanFactory.getType(beanName, false);
     if (beanType == null) {
      continue;
     }
     if (this.advisorFactory.isAspect(beanType)) {
      aspectNames.add(beanName);
      AspectMetadata amd = new AspectMetadata(beanType, beanName);
      if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
       MetadataAwareAspectInstanceFactory factory =
         new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
       List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
       if (this.beanFactory.isSingleton(beanName)) {
        this.advisorsCache.put(beanName, classAdvisors);
       }
       else {
        this.aspectFactoryCache.put(beanName, factory);
       }
       advisors.addAll(classAdvisors);
      }
      else {
       // Per target or per this.
       if (this.beanFactory.isSingleton(beanName)) {
        throw new IllegalArgumentException("Bean with name '" + beanName +
          "' is a singleton, but aspect instantiation model is not singleton");
       }
       MetadataAwareAspectInstanceFactory factory =
         new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
       this.aspectFactoryCache.put(beanName, factory);
       advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
     }
    }
    this.aspectBeanNames = aspectNames;
    return advisors;
   }
  }
 }
 if (aspectNames.isEmpty()) {
  return Collections.emptyList();
 }
 List<Advisor> advisors = new ArrayList<>();
 for (String aspectName : aspectNames) {
  List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
  if (cachedAdvisors != null) {
   advisors.addAll(cachedAdvisors);
  }
  else {
   MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
   advisors.addAll(this.advisorFactory.getAdvisors(factory));
  }
 }
 return advisors;
}

這個方法第一次進來的時候,aspectNames 變量是沒有值的,所以會先進入到 if 分支中,給 aspectNames 和 aspectBeanNames 兩個變量賦值。

具體過程就是首先調用 BeanFactoryUtils.beanNamesForTypeIncludingAncestors 方法(不熟悉該方法的小伙伴參考 Spring 中的父子容器是咋回事?一文),去當前容器以及當前容器的父容器中,查找到所有的 beanName,將返回的數組賦值給 beanNames 變量,然后對 beanNames 進行遍歷。

遍歷時,首先調用 isEligibleBean 方法,這個方法是檢查給定名稱的 Bean 是否符合自動代理的條件的,這個細節我們就不看了,因為一般情況下,我們項目中的 AOP 都是自動代理的。

接下來根據 beanName,找到對應的 bean 類型 beanType,然后調用 advisorFactory.isAspect 方法去判斷這個 beanType 是否是一個 Aspect,具體的判斷過程上篇文章講過了,小伙伴們可以參考。

如果當前 beanName 對應的 Bean 是一個 Aspect,那么就把 beanName 添加到 aspectNames 集合中,并且把 beanName 和 beanType 封裝為一個 AspectMetadata 對象。

接下來會去判斷 kind 是否為 SINGLETON,這個默認都是 SINGLETON,所以這里會進入到分支中,進來之后,會調用 this.advisorFactory.getAdvisors 方法去 Aspect 中找到各種通知和切點并封裝成 Advisor 對象返回,由于一個切面中可能定義多個通知,所以最終返回的 Advisor 是一個集合,最后把找到的 Advisor 集合存入到 advisorsCache 緩存中。

后面方法的邏輯就很好懂了,從 advisorsCache 中找到某一個 aspect 對應的所有 Advisor,并將之存入到 advisors 集合中,然后返回集合。

這樣,我們就找到了所有的 Advisor。

2.3.2 findAdvisorsThatCanApply

接下來 findAdvisorsThatCanApply 方法主要是從眾多的 Advisor 中,找到能匹配上當前 Bean 的 Advisor,小伙伴們知道,每一個 Advisor 都包含一個切點 Pointcut,不同的切點意味著不同的攔截規則,所以現在需要進行匹配,檢查當前類需要和哪個 Advisor 匹配:

protected List<Advisor> findAdvisorsThatCanApply(
  List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
 ProxyCreationContext.setCurrentProxiedBeanName(beanName);
 try {
  return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
 }
 finally {
  ProxyCreationContext.setCurrentProxiedBeanName(null);
 }
}

這里實際上就是調用了靜態方法 AopUtils.findAdvisorsThatCanApply 去查找匹配的 Advisor:

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
 if (candidateAdvisors.isEmpty()) {
  return candidateAdvisors;
 }
 List<Advisor> eligibleAdvisors = new ArrayList<>();
 for (Advisor candidate : candidateAdvisors) {
  if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
   eligibleAdvisors.add(candidate);
  }
 }
 boolean hasIntroductions = !eligibleAdvisors.isEmpty();
 for (Advisor candidate : candidateAdvisors) {
  if (candidate instanceof IntroductionAdvisor) {
   // already processed
   continue;
  }
  if (canApply(candidate, clazz, hasIntroductions)) {
   eligibleAdvisors.add(candidate);
  }
 }
 return eligibleAdvisors;
}

這個方法中首先會去判斷 Advisor 的類型是否是 IntroductionAdvisor 類型,IntroductionAdvisor 類型的 Advisor 只能在類級別進行攔截,靈活度不如 PointcutAdvisor,所以我們一般都不是 IntroductionAdvisor,因此這里最終會走入到最后一個分支中:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
 if (advisor instanceof IntroductionAdvisor ia) {
  return ia.getClassFilter().matches(targetClass);
 }
 else if (advisor instanceof PointcutAdvisor pca) {
  return canApply(pca.getPointcut(), targetClass, hasIntroductions);
 }
 else {
  // It doesn't have a pointcut so we assume it applies.
  return true;
 }
}

從這里小伙伴們就能看到,IntroductionAdvisor 類型的 Advisor 只需要調用 ClassFilter 過濾一下就行了,ClassFilter 松哥在前面的文章中已經介紹過了(玩一玩編程式 AOP),小伙伴們看這里的匹配邏輯也是非常 easy!而 PointcutAdvisor 類型的 Advisor 則會繼續調用 canApply 方法進行判斷:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
 if (!pc.getClassFilter().matches(targetClass)) {
  return false;
 }
 MethodMatcher methodMatcher = pc.getMethodMatcher();
 if (methodMatcher == MethodMatcher.TRUE) {
  // No need to iterate the methods if we're matching any method anyway...
  return true;
 }
 IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
 if (methodMatcher instanceof IntroductionAwareMethodMatcher iamm) {
  introductionAwareMethodMatcher = iamm;
 }
 Set<Class<?>> classes = new LinkedHashSet<>();
 if (!Proxy.isProxyClass(targetClass)) {
  classes.add(ClassUtils.getUserClass(targetClass));
 }
 classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
 for (Class<?> clazz : classes) {
  Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
  for (Method method : methods) {
   if (introductionAwareMethodMatcher != null ?
     introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
     methodMatcher.matches(method, targetClass)) {
    return true;
   }
  }
 }
 return false;
}

小伙伴們看一下,這里就是先按照類去匹配,匹配通過則繼續按照方法去匹配,方法匹配器要是設置的 true,那就直接返回 true 就行了,否則就加載當前類,也就是 targetClass,然后遍歷 targetClass 中的所有方法,最后調用 introductionAwareMethodMatcher.matches 方法去判斷方法是否和切點契合。

就這樣,我們就從所有的 Advisor 中找到了所有和當前類匹配的 Advisor 了。

2.3.3 extendAdvisors

這個是添加一個 DefaultPointcutAdvisor 切面進來,這個切面使用的 Advice 是 ExposeInvocationInterceptor,ExposeInvocationInterceptor 的作用是用于暴露 MethodInvocation 對象到 ThreadLocal 中,如果其他地方需要使用當前的 MethodInvocation 對象,直接通過調用 currentInvocation 方法取出即可。

這個方法的邏輯比較簡單,我就不貼出來了,小伙伴們可以自行查看。

2.4 createProxy

看完了 getAdvicesAndAdvisorsForBean 方法,我們已經找到了適合我們的 Advisor,接下來繼續看 createProxy 方法,這個方法用來創建一個代理對象:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  @Nullable Object[] specificInterceptors, TargetSource targetSource) {
 return buildProxy(beanClass, beanName, specificInterceptors, targetSource, false);
}
private Object buildProxy(Class<?> beanClass, @Nullable String beanName,
  @Nullable Object[] specificInterceptors, TargetSource targetSource, boolean classOnly) {
 if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
  AutoProxyUtils.exposeTargetClass(clbf, beanName, beanClass);
 }
 ProxyFactory proxyFactory = new ProxyFactory();
 proxyFactory.copyFrom(this);
 if (proxyFactory.isProxyTargetClass()) {
  // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
  if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
   // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
   for (Class<?> ifc : beanClass.getInterfaces()) {
    proxyFactory.addInterface(ifc);
   }
  }
 }
 else {
  // No proxyTargetClass flag enforced, let's apply our default checks...
  if (shouldProxyTargetClass(beanClass, beanName)) {
   proxyFactory.setProxyTargetClass(true);
  }
  else {
   evaluateProxyInterfaces(beanClass, proxyFactory);
  }
 }
 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
 proxyFactory.addAdvisors(advisors);
 proxyFactory.setTargetSource(targetSource);
 customizeProxyFactory(proxyFactory);
 proxyFactory.setFrozen(this.freezeProxy);
 if (advisorsPreFiltered()) {
  proxyFactory.setPreFiltered(true);
 }
 // Use original ClassLoader if bean class not locally loaded in overriding class loader
 ClassLoader classLoader = getProxyClassLoader();
 if (classLoader instanceof SmartClassLoader smartClassLoader && classLoader != beanClass.getClassLoader()) {
  classLoader = smartClassLoader.getOriginalClassLoader();
 }
 return (classOnly ? proxyFactory.getProxyClass(classLoader) : proxyFactory.getProxy(classLoader));
}

這段代碼不知道小伙伴們看了是否覺得眼熟,這就是前面發的另類 AOP,編程式 AOP!一文中的內容,所以這塊源碼大家自己看看就好了,我就不啰嗦了。


責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2022-09-29 09:17:47

進程Linux創建

2023-02-27 08:09:42

SpringAOP代理

2023-10-08 10:14:12

2022-09-01 10:40:29

SpringAOPJDK

2024-04-01 08:38:57

Spring@AspectAOP

2019-11-29 16:21:22

Spring框架集成

2012-07-11 14:31:16

SpringAop

2022-06-24 09:36:47

Python對象調用

2021-05-14 00:00:15

JavaScript開發代碼

2025-01-16 08:45:48

2023-03-29 08:24:30

2021-07-27 22:56:00

JavaScript編程開發

2021-07-01 10:45:18

Bean對象作用域

2020-06-22 08:50:27

Spring AOP代理

2024-11-04 16:29:19

2021-10-27 07:15:37

SpringAOP編程(

2024-03-04 07:41:18

SpringAOPOOP?

2010-04-26 08:53:06

面向方面編程.NET

2024-11-28 11:59:57

2009-06-16 15:02:18

面向對象編程PHP異常PHP代理
點贊
收藏

51CTO技術棧公眾號

亚洲精品一级二级| 亚洲av无码一区二区三区性色| 激情黄产视频在线免费观看| 成人久久视频在线观看| 2019中文字幕免费视频| 国产又粗又猛又爽视频| 电影中文字幕一区二区| 午夜av一区二区三区| 亚洲国产一区在线| 国产91久久久| 日韩影院在线观看| 欧美精品日韩三级| 亚洲av无码一区二区三区人| 精品国产亚洲一区二区在线观看 | 18深夜在线观看免费视频| 91高清视频在线观看| 国产精品入口麻豆原神| 高清视频一区二区三区| 欧美一区二区三区网站| 中文字幕一区二区三三| 亚洲色图色老头| wwwww在线观看| 久久久国产精品网站| 亚洲va欧美va人人爽| 少妇熟女一区二区| 欧美孕妇性xxxⅹ精品hd| 国产福利精品一区二区| 国产精品国产自产拍高清av水多| 欧美熟妇激情一区二区三区| h视频久久久| 在线电影一区二区三区| 又粗又黑又大的吊av| 在线播放免费av| 国产精品天美传媒沈樵| 欧美大香线蕉线伊人久久| 精品国产乱码一区二区三| 日韩av中文字幕一区二区| 亚州精品天堂中文字幕| 在线观看成人毛片| 99久久www免费| 视频直播国产精品| 人人爽人人爽人人片| 中文有码一区| 日韩精品丝袜在线| 国产又粗又长又爽| 日韩激情精品| 日韩欧美在线网站| 亚欧精品在线视频| 国产精品日本一区二区三区在线| 亚洲一区二区视频在线| 玖玖精品在线视频| av片在线观看网站| 亚洲人吸女人奶水| 法国空姐在线观看免费| 国产在线看片| 亚洲美女免费在线| 黄色一级视频播放| av在线app| 亚洲男人天堂一区| 日韩在线视频在线| 9lporm自拍视频区在线| 亚洲一二三区不卡| 欧美日韩性生活片| 午夜av不卡| 日韩欧美在线视频观看| 麻豆传传媒久久久爱| 日韩一级二级| 欧美年轻男男videosbes| 99九九99九九九99九他书对| crdy在线观看欧美| 日韩欧美成人激情| 少妇精品无码一区二区三区| 亚洲影院天堂中文av色| 国产性色av一区二区| 亚洲女人毛茸茸高潮| 正在播放日韩欧美一页| 欧美极品少妇与黑人| 综合激情网五月| 日本va欧美va欧美va精品| 成人a在线视频| 亚洲国产精品久久久久久6q| www.视频一区| 欧美亚洲免费在线| 五月天婷婷在线视频| 一区二区三区欧美日韩| 草草久久久无码国产专区| 韩国成人在线| 日韩欧美国产午夜精品| 精品夜夜澡人妻无码av| 久久网站免费观看| 久久久久成人网| 国产一区二区视频免费| 国产一区二区精品在线观看| 极品尤物一区二区三区| 触手亚洲一区二区三区| 一区av在线播放| 国产精品无码av无码| 久久久精品区| 国产一级揄自揄精品视频| 青草草在线视频| 鲁大师成人一区二区三区| 91九色单男在线观看| 天堂影院在线| 99久久夜色精品国产亚洲狼| 欧美二区在线播放| 亚洲乱码国产乱码精品| 国产精品99久久久久久宅男| 欧美福利精品| 免费污视频在线观看| 日本高清不卡aⅴ免费网站| 性久久久久久久久久久久久久| 成人av集中营| 亚洲国产精品专区久久| 国精品人伦一区二区三区蜜桃| 精品成人影院| 欧美极品少妇xxxxⅹ裸体艺术 | 日韩免费av在线| 国产av无码专区亚洲a∨毛片| 精品亚洲成a人| 乱色588欧美| 日本h片在线| 欧美日韩黄视频| 加勒比一区二区| 欧美日韩一视频区二区| 国产欧美日韩综合精品| 日本一区视频| 午夜精品久久久久久久久| 亚洲五月激情网| 国产伦精品一区二区三区千人斩| 在线不卡国产精品| 精品欧美一区二区三区免费观看| 久久xxxx| 久久精品欧美| 精品久久国产老人久久综合| 国产精品欧美一区二区三区奶水| 日本一区二区不卡在线| 欧美日韩国产系列| 久久久99精品视频| 国产福利亚洲| 精品亚洲精品福利线在观看| 国产亚洲第一页| 极品少妇xxxx精品少妇| 日日噜噜噜噜夜夜爽亚洲精品| 成人动漫在线播放| 一本色道**综合亚洲精品蜜桃冫| 亚洲欧美激情网| 国产成人精品免费视| 91国产中文字幕| 手机看片福利在线| 亚洲成人福利片| 又黄又爽的网站| 亚洲美洲欧洲综合国产一区| 国产精品区二区三区日本| 国内在线免费视频| 亚洲福利在线视频| 国产午夜久久久| av午夜一区麻豆| www.日本在线播放| 欧美亚洲大陆| 国产mv久久久| 国产高清在线| 欧美日本高清视频在线观看| 日韩av网站在线播放| 国产在线不卡视频| 激情五月六月婷婷| 日韩超碰人人爽人人做人人添| 一区二区国产精品视频| 中文字幕乱码中文字幕| 136国产福利精品导航| japan高清日本乱xxxxx| 亚洲国产欧美国产综合一区| 精品国产一区二区三区免费| 女人让男人操自己视频在线观看 | 国产69精品久久777的优势| 一区二区免费在线观看| 国产aa精品| 韩国精品久久久999| 久久精品一区二区三区av| 精品蜜桃一区二区三区| 在线天堂新版最新版在线8| 亚洲女人天堂av| 一区二区www| 一区二区国产视频| 在线免费看黄视频| 九一九一国产精品| 久久人人爽人人爽人人av| 日韩激情啪啪| 成人妇女免费播放久久久| 日本性爱视频在线观看| 精品亚洲一区二区| 国产免费不卡av| 日韩欧美亚洲范冰冰与中字| 中文字幕乱码av| 懂色av一区二区三区蜜臀| 欧美a在线视频| 91亚洲自偷观看高清| 精品久久一区二区三区蜜桃| 色婷婷成人网| 97精品视频在线观看| 欧美69xxxx| 亚洲欧美中文日韩在线v日本| 国产无遮挡又黄又爽又色| 91美女片黄在线| 91热视频在线观看| 久久成人亚洲| 欧美日韩中文字幕在线播放| 国产成人1区| 国产在线精品一区二区三区》| 大香伊人中文字幕精品| 亚洲色图综合网| 男人天堂综合网| 成人av电影在线观看| 热久久精品国产| 亚洲视屏一区| 青青草原国产免费| 国际精品欧美精品| 国产伦精品一区二区三| 国产精品久久久久久久久久久久久久久| 国产一区二区三区在线播放免费观看| 日韩精品一区二区亚洲av| 亚洲精品乱码久久久久久黑人| 中文字幕avav| 美女网站色91| 久草综合在线观看| 夜夜夜久久久| 全黄性性激高免费视频| 天天揉久久久久亚洲精品| 欧美一区二区三区在线播放| 国产欧美三级电影| 97在线电影| 91丨精品丨国产| 国产乱人伦真实精品视频| 高清不卡亚洲| 青草成人免费视频| 亚洲女色av| 人人澡人人澡人人看欧美| 九色porny自拍视频在线播放| 亚洲小视频在线观看| 深夜福利视频在线免费观看| 精品成a人在线观看| www.日韩高清| 欧美videos中文字幕| 午夜精品久久久久久久99老熟妇| 福利视频第一区| 久久久午夜影院| 精品国产31久久久久久| 欧美激情亚洲综合| 欧美日韩在线观看视频| 欧美啪啪小视频| 色婷婷久久久亚洲一区二区三区| 91 在线视频| 综合久久久久久久| 免费在线黄色网| 依依成人精品视频| 久久这里只有精品国产| 亚洲成人av在线电影| 久久久久亚洲av成人片| 亚洲成人精品在线观看| 97久久久久久久| 91国偷自产一区二区使用方法| 1024手机在线视频| 亚洲乱码中文字幕| 欧美一级高潮片| 婷婷一区二区三区| 伊人中文字幕在线观看| 在线观看一区二区视频| 在线观看国产小视频| 91麻豆精品国产91久久久 | 在线看免费av| 色婷婷av一区二区三区久久| av片在线观看网站| 992tv成人免费影院| 97成人资源| 国产区精品视频| 999久久久精品一区二区| 久久精品人成| 91精品推荐| 日韩精品xxxx| 麻豆91在线观看| 日本精品一二三区| 国产亚洲欧美日韩在线一区| 亚洲精品自拍视频在线观看| 亚洲高清不卡在线| 无码人妻丰满熟妇奶水区码| 91麻豆精品91久久久久久清纯| wwwwww在线观看| 日韩一区二区电影| 日韩欧美电影在线观看| 久久九九亚洲综合| 国产精品xx| 成人激情视频小说免费下载| 精品一区二区男人吃奶| 亚洲国产午夜伦理片大全在线观看网站 | 青春有你2免费观看完整版在线播放高清 | 欧洲大片精品免费永久看nba| 国产精品羞羞答答| 伊色综合久久之综合久久| 日本不卡二区| 国内在线观看一区二区三区| 中文字幕第21页| 国产成人精品影视| 性猛交ⅹxxx富婆video | 日韩av影视| 欧美精品色网| 亚洲老女人av| 成人综合在线观看| 午夜黄色福利视频| 狠狠躁夜夜躁人人爽天天天天97 | 在线成人小视频| 天天操天天插天天射| 久久国产精品久久久久久久久久| 国产黄色在线免费观看| 国产99久久精品一区二区永久免费| 日韩成人av电影| 国产日韩精品一区观看| 亚洲精品97| 天堂av8在线| 国产亚洲精品aa| 免费日韩一级片| 欧美大片一区二区三区| 久久日韩视频| 国产精品视频免费观看www| 亚洲免费成人av在线| 国产免费黄色一级片| 国产黄色91视频| 欧美日韩午夜视频| 欧美这里有精品| 国产一区精品| 国产成人在线一区| 啪啪激情综合网| ww国产内射精品后入国产| 国产成人亚洲综合a∨婷婷图片| 欧美无人区码suv| 亚洲国产精品一区二区尤物区| 中文字幕亚洲精品一区| 亚洲大胆人体av| 成年网站在线视频网站| julia一区二区中文久久94| 亚洲精品在线观看91| 911福利视频| 日本一区二区高清| 中文字幕+乱码+中文| 中文日韩在线观看| 久久电影天堂| 中文字幕欧美人与畜| 久久99国产精品久久99果冻传媒| 国产免费a级片| 亚洲一卡二卡三卡四卡无卡久久 | 久久精品中文字幕一区二区三区| 欧美三级美国一级| 天天影视综合色| 国产精品三级视频| 中文字幕无线码一区| 久久精品国产69国产精品亚洲| 三级中文字幕在线观看| 国产综合精品一区二区三区| 最新亚洲激情| 最近中文字幕免费视频| 在线观看视频欧美| 日本网站在线免费观看视频| 92看片淫黄大片看国产片| 欧美大片专区| 亚洲av人人澡人人爽人人夜夜| 国产精品国产三级国产普通话三级| 精品在线视频免费| 亚洲国产中文字幕久久网| sis001欧美| 中文字幕久久综合| 成人免费视频国产在线观看| 51国产偷自视频区视频| 在线亚洲午夜片av大片| 在线视频成人| 免费看黄在线看| 久久一区二区视频| 伊人免费在线观看高清版| 精品少妇v888av| 天天躁日日躁成人字幕aⅴ| 天天天干夜夜夜操| 一区二区在线观看视频在线观看| 91国偷自产中文字幕久久| 欧美精品在线免费| 视频福利一区| 中日韩av在线播放| 亚洲国产精品久久不卡毛片| 黄色大片在线看| 成人情趣片在线观看免费| 伊人久久大香线蕉综合热线| 久久久久久久久福利| 欧美成人官网二区| 精品免费av在线| 亚洲啊啊啊啊啊| 久久久午夜精品理论片中文字幕| 免费日韩一级片| 在线色欧美三级视频| 中文字幕久久精品一区二区| 激情婷婷综合网| 亚洲成人激情av| 国产区在线观看| 欧美精品一区二区视频| 国产经典欧美精品|