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

聊聊容器的始祖 DefaultListableBeanFactory

開發(fā) 前端
DefaultListableBeanFactory 是一個完整的、功能成熟的 IoC 容器,如果你的需求很簡單,甚至可以直接使用 DefaultListableBeanFactory,如果你的需求比較復(fù)雜,那么通過擴(kuò)展 DefaultListableBeanFactory 的功能也可以達(dá)到,可以說 DefaultListableBeanFactory 是整個 Spring IoC 容器的始祖。

[[333514]]

 1.DefaultListableBeanFactory

要說 XmlBeanFactory 就不得不先說它的父類 DefaultListableBeanFactory,因?yàn)?XmlBeanFactory 中的大部分功能實(shí)際上在 DefaultListableBeanFactory 中就已經(jīng)提供好了,XmlBeanFactory 只是對 IO 流的讀取做了一些定制而已。

DefaultListableBeanFactory 是一個完整的、功能成熟的 IoC 容器,如果你的需求很簡單,甚至可以直接使用 DefaultListableBeanFactory,如果你的需求比較復(fù)雜,那么通過擴(kuò)展 DefaultListableBeanFactory 的功能也可以達(dá)到,可以說 DefaultListableBeanFactory 是整個 Spring IoC 容器的始祖。

我們先來看一下 DefaultListableBeanFactory 的繼承關(guān)系:

從這張類的關(guān)系圖中可以看出,DefaultListableBeanFactory 實(shí)際上也是一個集大成者。在 Spring 中,針對 Bean 的不同操作都有不同的接口進(jìn)行規(guī)范,每個接口都有自己對應(yīng)的實(shí)現(xiàn),最終在 DefaultListableBeanFactory 中將所有的實(shí)現(xiàn)匯聚到一起。從這張類的繼承關(guān)系圖中我們大概就能感受到 Spring 中關(guān)于類的設(shè)計是多么厲害,代碼耦合度非常低。

這些類,在本系列后面的介紹中,大部分都會涉及到,現(xiàn)在我先大概介紹一下每個類的作用,大家先混個臉熟:

  1. BeanFactory:這個接口看名字就知道是一個 Bean 的工廠,BeanFactory 接口定義了各種獲取 Bean 的方法、判斷 Bean 是否存在、判斷 Bean 是否單例等針對 Bean 的基礎(chǔ)方法。
  2. ListableBeanFactory:這個接口繼承自 BeanFactory,在 BeanFactory 的基礎(chǔ)上,擴(kuò)展了 Bean 的查詢方法,例如根據(jù)類型獲取 BeanNames、根據(jù)注解獲取 BeanNames、根據(jù) Bean 獲取注解等。
  3. AutowireCapableBeanFactory:該接口繼承自 BeanFactory,在 BeanFactory 的基礎(chǔ)上,提供了 Bean 的創(chuàng)建、配置、注入、銷毀等操作。有時候我們需要自己手動注入 Bean 的時候,可以考慮通過實(shí)現(xiàn)該接口來完成。AutowireCapableBeanFactory 在 Spring Security 中有一個重要的應(yīng)用就是 ObjectPostProcessor,這個松哥將在 ??Spring Security 系列中和大家詳細(xì)介紹。
  4. HierarchicalBeanFactory:該接口繼承自 BeanFactory,并在 BeanFactory 基礎(chǔ)上添加了獲取 parent beanfactory 的方法。
  5. SingletonBeanRegistry:這個接口定義了對單例 Bean 的定義以及獲取方法。
  6. ConfigurableBeanFactory:這個接口主要定了針對 BeanFactory 的各種配置以及銷毀的方法。
  7. ConfigurableListableBeanFactory:這是 BeanFactory 的配置清單,這里定義了忽略的類型、接口,通過 Bean 的名稱獲取 BeanDefinition 、凍結(jié) BeanDefinition 等。
  8. AliasRegistry:這個接口定義了對 alias 的注冊、移除、判斷以及查詢操作。
  9. SimpleAliasRegistry:這個類實(shí)現(xiàn)了 AliasRegistry 接口并實(shí)現(xiàn)了它里邊的方法,SimpleAliasRegistry 使用 ConcurrentHashMap 做載體,實(shí)現(xiàn)了對 alias 的注冊、移除判斷以及查詢操作。
  10. DefaultSingletonBeanRegistry:這個類基于 Java 中的集合,對 SingletonBeanRegistry 接口進(jìn)行了實(shí)現(xiàn)。
  11. FactoryBeanRegistrySupport:該類繼承自 DefaultSingletonBeanRegistry,并在 DefaultSingletonBeanRegistry 的基礎(chǔ)上,增加了獲取 FactoryBean 類型、移除 FactoryBean 緩存的方法等等操作。
  12. AbstractBeanFactory:實(shí)現(xiàn)了 ConfigurableBeanFactory 接口并繼承自 FactoryBeanRegistrySupport,在 AbstractBeanFactory 中對 ConfigurableBeanFactory 中定義的方法進(jìn)行了實(shí)現(xiàn)。
  13. AbstractAutowireCapableBeanFactory:該類繼承自 AbstractBeanFactory 并對 AutowireCapableBeanFactory 接口中定義的方法進(jìn)行了落地實(shí)現(xiàn)。
  14. BeanDefinitionRegistry:這個接口繼承自 AliasRegistry 接口,并增加了一系列針對 BeanDefinition 的注冊、移除、查詢、判斷等方法。
  15. 最后的 DefaultListableBeanFactory 自然就具備了上面所有的功能。

上面的內(nèi)容可能看的大家眼花繚亂,松哥這里通過幾個簡單實(shí)際的例子,來帶大家使用一下 DefaultListableBeanFactory 的功能,可能大家的理解就比較清晰了。

DefaultListableBeanFactory 作為一個集大成者,提供了非常多的功能,我們一個一個來看。

2.代碼改造

首先文章中一開始的三行代碼我們可以對其略加改造,因?yàn)槲覀円呀?jīng)說了 XmlBeanFactory 中的大部分功能實(shí)際上在 DefaultListableBeanFactory 中就已經(jīng)提供好了,XmlBeanFactory 只是對 IO 流的讀取做了一些定制而已,文件的讀取主要是通過 XmlBeanDefinitionReader 來完成的(本系列前面文章已經(jīng)講過),我們可以對文章一開始的三行代碼進(jìn)行改造,以便更好的體現(xiàn)“XmlBeanFactory 中的大部分功能實(shí)際上在 DefaultListableBeanFactory 中就已經(jīng)提供好了”:

  1. ClassPathResource res=new ClassPathResource("beans.xml"); 
  2. DefaultListableBeanFactory factory=new DefaultListableBeanFactory(); 
  3. XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(factory); 
  4. reader.loadBeanDefinitions(res); 
  5. User user = factory.getBean(User.class); 
  6. System.out.println("user = " + user); 

使用前四行代碼代替 XmlBeanFactory,這樣 XmlBeanFactory 的功能是不是就很明確了?就是前四行代碼的功能。

3.動態(tài)注冊 Bean

動態(tài)注冊 Bean,這是 DefaultListableBeanFactory 的功能之一,不過準(zhǔn)確來說應(yīng)該是動態(tài)注冊 BeanDefinition 。

我們先來看一個簡單的例子:

  1. DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory(); 
  2. GenericBeanDefinition userBeanDefinition = new GenericBeanDefinition(); 
  3. MutablePropertyValues pvs = new MutablePropertyValues(); 
  4. pvs.add("username""javaboy"); 
  5. pvs.add("address""www.javaboy.org"); 
  6. userBeanDefinition.setPropertyValues(pvs); 
  7. userBeanDefinition.setBeanClass(User.class); 
  8. defaultListableBeanFactory.registerBeanDefinition("user", userBeanDefinition); 
  9. User user = defaultListableBeanFactory.getBean(User.class); 
  10. System.out.println("user = " + user); 

首先我們自己手動構(gòu)建一個 DefaultListableBeanFactory 對象。當(dāng)然也可以使用前面的 XmlBeanFactory。

然后再手動構(gòu)建一個 GenericBeanDefinition。在前面的文章中,松哥和大家講過,現(xiàn)在默認(rèn)使用的 BeanDefinition 就是 GenericBeanDefinition,所以這里我們自己也手動構(gòu)建一個 GenericBeanDefinition。有了 GenericBeanDefinition 之后,我們設(shè)置相關(guān)的類和屬性。

接下來再將 userBeanDefinition 注冊到 defaultListableBeanFactory。注冊完成之后,我們就可以從 defaultListableBeanFactory 中獲取相應(yīng)的 Bean 了。

這里說一句題外話,希望大家在閱讀本系列每一篇文章的時候,能夠?qū)⒈鞠盗星昂笪恼侣?lián)系起來一起理解,這樣會有很多意料之外的收獲。例如上面的,我們既可以聲明一個 DefaultListableBeanFactory,也可以聲明一個 XmlBeanFactory,那你大概就能據(jù)此推斷出 XmlBeanFactory 的主要目的可能就是對資源文件進(jìn)行讀取和注冊。

那么到底是怎么注冊的呢?我們來看一下 defaultListableBeanFactory.registerBeanDefinition 方法的定義:

  1. @Override 
  2. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 
  3.   throws BeanDefinitionStoreException { 
  4.  Assert.hasText(beanName, "Bean name must not be empty"); 
  5.  Assert.notNull(beanDefinition, "BeanDefinition must not be null"); 
  6.  if (beanDefinition instanceof AbstractBeanDefinition) { 
  7.   try { 
  8.    ((AbstractBeanDefinition) beanDefinition).validate(); 
  9.   } 
  10.   catch (BeanDefinitionValidationException ex) { 
  11.    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 
  12.      "Validation of bean definition failed", ex); 
  13.   } 
  14.  } 
  15.  BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); 
  16.  if (existingDefinition != null) { 
  17.   if (!isAllowBeanDefinitionOverriding()) { 
  18.    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); 
  19.   } 
  20.   else if (existingDefinition.getRole() < beanDefinition.getRole()) { 
  21.    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE 
  22.    if (logger.isInfoEnabled()) { 
  23.     logger.info("Overriding user-defined bean definition for bean '" + beanName + 
  24.       "' with a framework-generated bean definition: replacing [" + 
  25.       existingDefinition + "] with [" + beanDefinition + "]"); 
  26.    } 
  27.   } 
  28.   else if (!beanDefinition.equals(existingDefinition)) { 
  29.    if (logger.isDebugEnabled()) { 
  30.     logger.debug("Overriding bean definition for bean '" + beanName + 
  31.       "' with a different definition: replacing [" + existingDefinition + 
  32.       "] with [" + beanDefinition + "]"); 
  33.    } 
  34.   } 
  35.   else { 
  36.    if (logger.isTraceEnabled()) { 
  37.     logger.trace("Overriding bean definition for bean '" + beanName + 
  38.       "' with an equivalent definition: replacing [" + existingDefinition + 
  39.       "] with [" + beanDefinition + "]"); 
  40.    } 
  41.   } 
  42.   this.beanDefinitionMap.put(beanName, beanDefinition); 
  43.  } 
  44.  else { 
  45.   if (hasBeanCreationStarted()) { 
  46.    // Cannot modify startup-time collection elements anymore (for stable iteration) 
  47.    synchronized (this.beanDefinitionMap) { 
  48.     this.beanDefinitionMap.put(beanName, beanDefinition); 
  49.     List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); 
  50.     updatedDefinitions.addAll(this.beanDefinitionNames); 
  51.     updatedDefinitions.add(beanName); 
  52.     this.beanDefinitionNames = updatedDefinitions; 
  53.     removeManualSingletonName(beanName); 
  54.    } 
  55.   } 
  56.   else { 
  57.    // Still in startup registration phase 
  58.    this.beanDefinitionMap.put(beanName, beanDefinition); 
  59.    this.beanDefinitionNames.add(beanName); 
  60.    removeManualSingletonName(beanName); 
  61.   } 
  62.   this.frozenBeanDefinitionNames = null
  63.  } 
  64.  if (existingDefinition != null || containsSingleton(beanName)) { 
  65.   resetBeanDefinition(beanName); 
  66.  } 
  67.  else if (isConfigurationFrozen()) { 
  68.   clearByTypeCache(); 
  69.  } 

registerBeanDefinition 方法是在 BeanDefinitionRegistry 接口中聲明的,DefaultListableBeanFactory 類實(shí)現(xiàn)了 BeanDefinitionRegistry 接口,并實(shí)現(xiàn)了該方法,我們來看分析下該方法:

  • 首先對傳入的 beanDefinition 對象進(jìn)行校驗(yàn),這也是注冊前的最后一次校驗(yàn),不過這個時候 BeanDefinition 對象已經(jīng)到手了,所以這個校驗(yàn)并非 XML 文件校驗(yàn),這里主要是對 methodOverrides 的校驗(yàn)。
  • 接下來會根據(jù) beanName 從 beanDefinitionMap 中獲取 BeanDefinition,看看當(dāng)前 Bean 是否已經(jīng)定義過了。beanDefinitionMap 是一個 Map 集合,這個集合中 key 是 beanName,value 是 BeanDefinition 對象。
  • 如果 BeanDefinition 已經(jīng)存在了,那么接下來會判斷是否允許 BeanDefinition 覆蓋,如果不允許,就直接拋出異常(不知道小伙伴們有沒有印象,在松哥前面的 OAuth2 系列教程中,經(jīng)常需要配置允許 BeanDefinition 的覆蓋,就是因?yàn)檫@個原因,公眾號【江南一點(diǎn)雨】后臺回復(fù) OAuth2 獲取該教程),如果允許 BeanDefinition 的覆蓋,那就向 beanDefinitionMap 中再次存一次值,覆蓋之前的值。
  • 如果 BeanDefinition 不存在,那就直接注冊。直接注冊分兩種情況:項目已經(jīng)運(yùn)行了和項目還沒運(yùn)行。
  • 如果項目已經(jīng)運(yùn)行,由于 beanDefinitionMap 是一個全局變量,可能存在并發(fā)問題,所以要加鎖處理。否則就直接注冊,所謂的注冊就是把對象存入 beanDefinitionMap 中,同時將 beanName 都存入 beanDefinitionNames 集合中。

這便是 registerBeanDefinition 方法的工作流程。

有小伙伴會說,這個方法從頭到尾都是 BeanDefinition,跟 Bean 有什么關(guān)系呢?

咋一看確實(shí)好像和 Bean 沒有直接關(guān)系。

其實(shí)這涉及到另外一個問題,就是 Bean 的懶加載。這個時候先把 BeanDefinition 定義好,等到真正調(diào)用 Bean 的時候,才會去初始化 Bean。我們可以在 User 類的構(gòu)造方法中打印日志看下,如下:

  1. public class User { 
  2.     private String username; 
  3.     private String address; 
  4.  
  5.     public User() { 
  6.         System.out.println("--------user init--------"); 
  7.     } 
  8.  
  9.     @Override 
  10.     public String toString() { 
  11.         return "User{" + 
  12.                 "username='" + username + '\'' + 
  13.                 ", address='" + address + '\'' + 
  14.                 '}'
  15.     } 
  16.  
  17.     public String getUsername() { 
  18.         return username; 
  19.     } 
  20.  
  21.     public void setUsername(String username) { 
  22.         this.username = username; 
  23.     } 
  24.  
  25.     public String getAddress() { 
  26.         return address; 
  27.     } 
  28.  
  29.     public void setAddress(String address) { 
  30.         this.address = address; 
  31.     } 

從下圖可以看到,當(dāng) BeanDefinition 注冊完成后,User 并沒有初始化,等到 getBean 方法被調(diào)用的時候,User 才初始化了。

需要注意的是,我們?nèi)粘i_發(fā)中使用的 ApplicationContext 并非懶加載,這個在松哥的 Spring 入門視頻中可以看到效果【??https://www.bilibili.com/video/BV1Wv41167TU】,具體原理松哥將在本系列后面的文章中和大家分享。

那么如果不想懶加載該怎么辦呢?當(dāng)然有辦法。

4.提前注冊 Bean

在 DefaultListableBeanFactory 中還有一個 preInstantiateSingletons 方法可以提前注冊 Bean,該方法是在 ConfigurableListableBeanFactory 接口中聲明的,DefaultListableBeanFactory 類實(shí)現(xiàn)了 ConfigurableListableBeanFactory 接口并實(shí)現(xiàn)了接口中的方法:

  1. @Override 
  2. public void preInstantiateSingletons() throws BeansException { 
  3.  if (logger.isTraceEnabled()) { 
  4.   logger.trace("Pre-instantiating singletons in " + this); 
  5.  } 
  6.  // Iterate over a copy to allow for init methods which in turn register new bean definitions. 
  7.  // While this may not be part of the regular factory bootstrap, it does otherwise work fine. 
  8.  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); 
  9.  // Trigger initialization of all non-lazy singleton beans... 
  10.  for (String beanName : beanNames) { 
  11.   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 
  12.   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 
  13.    if (isFactoryBean(beanName)) { 
  14.     Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 
  15.     if (bean instanceof FactoryBean) { 
  16.      final FactoryBean<?> factory = (FactoryBean<?>) bean; 
  17.      boolean isEagerInit; 
  18.      if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 
  19.       isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) 
  20.           ((SmartFactoryBean<?>) factory)::isEagerInit, 
  21.         getAccessControlContext()); 
  22.      } 
  23.      else { 
  24.       isEagerInit = (factory instanceof SmartFactoryBean && 
  25.         ((SmartFactoryBean<?>) factory).isEagerInit()); 
  26.      } 
  27.      if (isEagerInit) { 
  28.       getBean(beanName); 
  29.      } 
  30.     } 
  31.    } 
  32.    else { 
  33.     getBean(beanName); 
  34.    } 
  35.   } 
  36.  } 
  37.  // Trigger post-initialization callback for all applicable beans... 
  38.  for (String beanName : beanNames) { 
  39.   Object singletonInstance = getSingleton(beanName); 
  40.   if (singletonInstance instanceof SmartInitializingSingleton) { 
  41.    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 
  42.    if (System.getSecurityManager() != null) { 
  43.     AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 
  44.      smartSingleton.afterSingletonsInstantiated(); 
  45.      return null
  46.     }, getAccessControlContext()); 
  47.    } 
  48.    else { 
  49.     smartSingleton.afterSingletonsInstantiated(); 
  50.    } 
  51.   } 
  52.  } 

preInstantiateSingletons 方法的整體邏輯比較簡單,就是遍歷 beanNames,對符合條件的 Bean 進(jìn)行實(shí)例化,而且大家注意,這里所謂的提前初始化其實(shí)就是在我們調(diào)用 getBean 方法之前,它自己先調(diào)用了一下 getBean。

我們可以在案例中手動調(diào)用該方法:

  1. DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory(); 
  2. GenericBeanDefinition userBeanDefinition = new GenericBeanDefinition(); 
  3. MutablePropertyValues pvs = new MutablePropertyValues(); 
  4. pvs.add("username""javaboy"); 
  5. pvs.add("address""www.javaboy.org"); 
  6. userBeanDefinition.setPropertyValues(pvs); 
  7. userBeanDefinition.setBeanClass(User.class); 
  8. defaultListableBeanFactory.registerBeanDefinition("user", userBeanDefinition); 
  9. defaultListableBeanFactory.preInstantiateSingletons(); 
  10. User user = defaultListableBeanFactory.getBean(User.class); 
  11. System.out.println("user = " + user); 

此時在調(diào)用 getBean 方法之前,User 就已經(jīng)初始化了,如下圖:

 

5.getBean

DefaultListableBeanFactory 中另外一個重量級方法就是 getBean 了。不過 getBean 方法的真正實(shí)現(xiàn)是在 DefaultListableBeanFactory 的父類 AbstractBeanFactory 中,具體的實(shí)現(xiàn)方法是 doGetBean,本來想和大家子在這里聊一聊這個問題,但是發(fā)現(xiàn)這是一個非常龐大的問題,BeanFactory 和 FactoryBean 都還沒和大家分享,所以這個話題我們還是暫且押后,一個點(diǎn)一個點(diǎn)來。

6.小結(jié)

 

好啦,今天就先說這么多,每篇源碼我都盡量配置套一些小案例來演示,這樣避免大家看的太枯燥了,我們下周繼續(xù)~

本文轉(zhuǎn)載自微信公眾號「江南一點(diǎn)雨 」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系江南一點(diǎn)雨公眾號。

 

責(zé)任編輯:武曉燕 來源: 江南一點(diǎn)雨
相關(guān)推薦

2020-12-03 09:50:52

容器IoC流程

2024-05-09 09:55:08

2022-03-04 08:45:11

Docker開源Linux

2020-06-10 08:28:51

Kata容器I

2023-04-28 08:43:46

2024-08-05 11:14:45

2021-09-14 13:25:23

容器pod僵尸進(jìn)程

2022-01-19 08:01:13

Linuxdocker容器

2018-04-24 09:05:09

容器存儲接口

2023-07-03 09:59:00

并發(fā)編程并發(fā)容器

2022-01-05 00:03:32

場景容器Airflow

2023-11-28 07:55:05

Calico容器網(wǎng)絡(luò)

2020-06-10 08:55:36

Docker容器工具

2024-07-26 09:47:28

2024-01-30 09:14:35

容器資源管理

2020-05-06 22:07:53

UbuntuLinux操作系統(tǒng)

2023-07-04 08:06:40

數(shù)據(jù)庫容器公有云

2020-11-23 07:00:38

代碼美顏 格式化

2023-11-02 09:25:42

springSystem

2021-01-14 08:58:12

Synchronize鎖操作
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

最新不卡av| 日韩子在线观看| 中文字幕日韩精品久久| 色婷婷精品大在线视频| 红杏视频成人| 欧美另类视频在线观看| 成人写真福利网| 国产精品网站在线| 国产成人福利夜色影视| 久久精品国产亚洲av麻豆| 孩xxxx性bbbb欧美| 95精品视频在线| 最近在线中文字幕| 亚洲欧美色图视频| 国产精品一区二区久久精品 | 999久久久亚洲| 亚洲一区二区色| 糖心vlog在线免费观看| 欧美一级日韩不卡播放免费| 欧美成人日韩| 亚洲av成人无码网天堂| 欧美极品欧美精品欧美图片| 怡红院精品视频| 精品一区二区综合| 国产盗摄一区二区| 色天使在线视频| 国产日韩中文字幕| 午夜精品久久久久久久久| 亚洲黄色录像| 国产浮力第一页| 丰满少妇被猛烈进入高清播放| 国产午夜精品一区二区三区| 国产精品一区二区三区网站| 午夜欧美巨大性欧美巨大| 婷婷社区五月天| 欧美日韩精品免费看| 日韩视频一区二区| 久久99最新地址| 亚洲欧美电影| 国产亚洲精品久久777777| 亚洲 日韩 国产第一区| 日韩电影在线观看中文字幕 | 国产精品视区| 羞羞视频在线观看免费| 在线观看免费小视频| 国产私拍一区| 亚洲国产婷婷香蕉久久久久久| 久久99精品久久久久久动态图| 玛雅亚洲电影| 久久久久久久久久久久久av| 免费高清一区二区三区| 久久亚洲影音av资源网| 成人免费在线播放视频| 日韩aaaa| 欧美jizzhd69巨大| 神马午夜精品91| 亚洲一区在线直播| 色综合亚洲精品激情狠狠| 国产亚洲精品免费| 波多野结衣一区| 国内av一区二区三区| 久久久久无码精品国产sm果冻| 欧美国产综合视频| 中文字幕国产亚洲2019| 国产精品国产自产拍高清av| 久久中文字幕av| a免费在线观看| 国语对白一区二区| 黄色av网址在线播放| 国产成人在线精品| 制服丝袜中文字幕一区| 99久久婷婷国产综合精品电影| 亚洲第一二三区| 亚洲图片88| 日韩高清免费av| 污污的视频免费| 精品国产中文字幕| 中文字幕亚洲综合| 亚洲国产成人91porn| 三级影片在线观看欧美日韩一区二区| 四虎精品在线观看| 国产成人无码www免费视频播放| jizz日本免费| 国产在线观看欧美| 国产精品久久久久9999| 欧美mv日韩mv国产网站| 国产精品网友自拍| 免费一区视频| 国产精品videossex| 午夜视频成人| 成人毛片一区二区三区| xxxxxx黄色| 成年在线观看视频| 成人淫片在线看| 亚洲精选一区二区| 天天av天天翘天天综合网| 国产乱妇无码大片在线观看| 国产一区二区欧美| 亚洲深夜视频| 香蕉久久一区二区三区| 国产一级免费观看| 欧美体内she精高潮| 大地资源第二页在线观看高清版| 国产精品久久久久久超碰| 亚洲精品视频免费| 疯狂做受xxxx高潮欧美日本| 成人精品视频一区| 国产一区二区三区久久| 日韩美女精品| 亚洲播播91| 98在线视频| 91亚洲精品国偷拍自产在线观看 | 成人性生交大片免费网站 | 亚洲一区二区网站| 九九久久婷婷| 欧洲成人一区| 亚洲资源一区| 欧美自拍第一页| 中文字幕精品三级久久久| 国产熟妇久久777777| 亚洲一级片网站| 热久久最新网址| 精品乱码一区二区三区| 国产精品video| 久久夜色精品国产亚洲aⅴ| 日韩欧美黄色影院| 欧美日韩激情视频| 中文一区二区在线观看| 国产伦精品一区二区三区免费| 伊人成人在线| 欧美日韩精品一区二区视频| 欧美三级一区| 成人高清一区| 成人黄色动漫| 日本高清成人vr专区| 青青操在线视频| 欧美 日韩 国产 成人 在线| 中文字字幕在线观看| 国产一级特黄aaa大片| 永久免费看片视频教学| 中文字幕国产综合| 黄色在线免费播放| а 天堂 在线| 久久久久久久久久一区| 黄色免费网址大全| 日韩一级片播放| 国产亚洲天堂网| 久操网在线观看| 免费拍拍拍网站| 欧美狂野激情性xxxx在线观| 日韩视频在线观看视频| 正在播放91九色| 中文字幕一区二区三区最新| 日本日本精品二区免费| 日产精品一线二线三线芒果| 欧美激情一区二区三区在线视频| 国产麻豆日韩| 久久久一本精品99久久精品66| 国产美女精品久久久| 国产综合精品一区二区三区| 国产亚洲精品美女久久久m| 国产精品日韩高清| 老司机精品福利在线观看| 九九九九九九精品| 欧美日韩精品免费看| 一本一道久久a久久精品综合| 一区二区免费电影| 永久免费看av| 北条麻妃在线视频观看| 日本精品一区二区三区四区| a在线观看免费视频| 日韩欧美中文视频| 捆绑凌虐一区二区三区| 色屁屁草草影院ccyy.com| 卡通动漫亚洲综合| 五月天婷婷综合网| 国产裸体美女永久免费无遮挡| 91无套直看片红桃| 欧美拍拍视频| 午夜伦理大片视频在线观看| aa国产成人| 国产欧美88| 久久99免费视频| 91精品亚洲| 老**午夜毛片一区二区三区| 国模一区二区三区白浆| 91视频你懂的| 一区二区免费在线播放| 欧美日韩情趣电影| 亚洲欧美成人精品| 欧美激情欧美激情| 亚洲一区二区免费在线| 日本一区不卡| 国产美女无遮挡网站| 91人妻一区二区| 欧美偷拍第一页| 又色又爽又黄无遮挡的免费视频| 亚洲 美腿 欧美 偷拍| 韩国av网站在线| 国产精品99久久免费| 欧美大人香蕉在线| 免费成人av资源网| 国产欧美一区视频| 狠狠躁夜夜躁久久躁别揉| 日韩精品在线观看视频| 97成人在线视频| 欧美成人免费在线| 久草福利视频在线| 成人一级片免费看| 亚洲自拍第二页| 国产视频在线播放| 亚洲国产欧美国产第一区| 亚洲视频在线免费| 成人精品视频一区二区三区尤物| 亚洲第一在线综合网站| 亚洲精品久久久一区二区三区| 欧洲成人性视频| 亚洲成人精品电影在线观看| 我看黄色一级片| 国产一级理论片| 国产永久免费高清在线观看| 国产成人a视频高清在线观看| 午夜久久99| 久久久久久久久久美女| 欧美日韩国产小视频| 久久男人资源视频| 午夜欧美一区二区三区免费观看| 九一精品久久久| 亚洲视频免费播放| 日本视频不卡| 欧洲亚洲一区二区三区| 狠狠v欧美v日韩v亚洲ⅴ| 亚洲成国产人片在线观看| 亚洲图片欧美日产| 国产在线一区二| 午夜激情视频网| 国产女主播喷水视频在线观看 | 国产成人精品影视| 欧美在线观看一二区| 久久久综合免费视频| 裸体裸乳免费看| 亚洲高潮女人毛茸茸| 日本人妖在线| 欧美a大片欧美片| 国产传媒久久文化传媒| 欧美人成免费网站| 国产精品第100页| 久久久久久久久久久久久国产精品 | 自拍另类欧美| 免费看91的网站| 欧美扣逼视频| 女人av一区| 久久亚洲影视婷婷| 日韩精品中文字幕在线| 国产一区二区三区高清视频| 无码人妻一区二区三区一| 精品久久无码中文字幕| 日韩精品久久久久久久软件91 | 久久在线免费视频| 在线精品日韩| 成年人av电影| 亚洲区欧洲区| 国内精品久久久久久久影视麻豆| 一片黄亚洲嫩模| 久久久亚洲成人| 久久久久狠狠高潮亚洲精品| 日本视频在线观看免费| 国产成人午夜性a一级毛片| 激情伊人五月天久久综合| 日韩一区二区精品在线观看| 国产成人精品自拍| 97人妻精品一区二区免费| 中文字幕欧美色图| 182在线视频观看| 欧美大肥婆大肥bbbbb| 男女在线视频| 欧美又大又硬又粗bbbbb| 韩国成人在线| 91美女高潮出水| 国产成人福利av| 欧美一区二区综合| 五月激情综合| 久无码久无码av无码| 米奇777在线欧美播放| 岛国av在线免费| 东方aⅴ免费观看久久av| 18禁裸乳无遮挡啪啪无码免费| 欧美激情综合网| 久视频在线观看| 色婷婷精品久久二区二区蜜臂av| 97在线播放免费观看| 亚洲成人亚洲激情| av网站在线免费播放| 欧美丰满少妇xxxxx| 免费观看成人性生生活片| 亚洲在线免费看| 免费看日本一区二区| 青青草影院在线观看| 性xx色xx综合久久久xx| 午夜激情视频网| 国产日产精品1区| xxxx 国产| 欧美精品xxxxbbbb| 裸体xxxx视频在线| 色综合色综合久久综合频道88| 日韩高清中文字幕一区二区| 99免费在线观看视频| 欧美日韩水蜜桃| 男女私大尺度视频| 国产在线精品不卡| 亚洲色成人网站www永久四虎| 亚洲人成网站在线| 黄色大全在线观看| 日韩精品视频免费在线观看| 97影院秋霞午夜在线观看| 国产成人精品久久二区二区91| 伊人久久大香线蕉av超碰| 亚洲成人网上| 久久xxxx精品视频| 伊人久久一区二区三区| 综合在线观看色| 国产精品51麻豆cm传媒| 日韩激情视频在线| caoporn-草棚在线视频最| 亚洲tv在线观看| 日韩电影在线视频| 日本三区在线观看| 91丝袜高跟美女视频| 日本免费在线播放| 日韩一区二区精品在线观看| 黄网站免费在线观看| 日韩免费在线观看视频| 欧美wwwsss9999| 无码av天堂一区二区三区| 国产米奇在线777精品观看| 久久av红桃一区二区禁漫| 欧美三级韩国三级日本一级| 国产高清视频在线播放| 国产www精品| 精品72久久久久中文字幕| 亚洲精品无码久久久久久| 91丝袜高跟美女视频| 天天干天天干天天| 亚洲欧美国产精品va在线观看| 超碰99在线| 精品国产日本| 久久精品动漫| 免费一级做a爰片久久毛片潮| 日本久久一区二区三区| 国产视频网站在线| 国产精品久久久久久av福利软件 | 91精品国产综合久久精品app| 亚洲精品承认| 91精品免费看| 91精品久久久久久久蜜月| 久久久久亚洲av无码麻豆| 一区二区三区美女| 风流老熟女一区二区三区| 性色av一区二区三区红粉影视| 精品按摩偷拍| 欧美视频第一区| 国产欧美日本一区视频| 一区二区视频免费观看| 久99久在线视频| 国产精品22p| 欧美国产激情视频| 国产日韩av一区| 国产精品无码AV| 欧美黑人xxx| 日韩欧美美女在线观看| 少妇性l交大片| 国产精品视频九色porn| 亚洲视频一区二区三区四区| 超碰97人人做人人爱少妇| 国产成人在线中文字幕| 久久久久久久久久福利| 中文字幕亚洲一区二区va在线| 国产成人精品免费看视频| 97精品在线视频| 成人无号精品一区二区三区| 男男受被啪到高潮自述| 午夜精品福利一区二区三区av| 国产永久免费高清在线观看| 成人欧美一区二区三区在线湿哒哒| 国产一区日韩欧美| 国产熟妇久久777777| 日韩一区二区三区在线视频| 蜜桃视频在线网站| 在线成人性视频| 97se亚洲国产综合自在线观| 中文字幕理论片| 欧美精品videossex88| av一区二区高清| 色哟哟视频在线| 欧美四级电影在线观看| 在线xxxx| 亚洲国产精品视频一区| 成人禁用看黄a在线| 一级特黄色大片| 欧美最猛黑人xxxx黑人猛叫黄|