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

我試圖通過這篇文章,教會你一種閱讀源碼的方式

開發 前端
閱讀源碼的方式非常的多,這篇文章只是站在我個人的角度介紹閱讀源碼的眾多方式中的一種,滄海一粟,就像是一片樹林里面的一棵樹的樹干上的一葉葉片的葉脈中的一個小分叉而已。

你好呀,我是歪歪。

是的,正如標題描述的這樣,我試圖通過這篇文章,教會你如何閱讀源碼。

事情大概是這樣的,前段時間,我收到了一個讀者發來的類似于這樣的示例代碼:

圖片

他說他知道這三個案例的回滾情況是這樣的:

  • insertTestNoRollbackFor:不會回滾
  • insertTestRollback:會回滾
  • insertTest:會回滾

他說在沒有執行代碼之前,他也知道前兩個為什么一個不會回滾,一個會回滾。因為拋出的異常和 @Transactional 里面的注解呼應上了。

但是第三個到底會不會回滾,沒有執行之前,他不知道為什么會回滾。執行之后,回滾了,他也不知道為什么回滾了。

我告訴他:源碼之下無秘密。

讓他去看看這部分源碼,理解它的原理,不然這個地方拋出一個其他的異常,又不知道會不會回滾了。

但是他說他完全不會看源碼,找不到下手的角度。

圖片

所以,就這個問題,我打算寫這樣的一篇文章,試圖教會你一種閱讀源碼的方式。讓你找到一個好的切入點,或者說突破口。

但是需要事先說明的是,閱讀源碼的方式非常的多,這篇文章只是站在我個人的角度介紹閱讀源碼的眾多方式中的一種,滄海一粟,就像是一片樹林里面的一棵樹的樹干上的一葉葉片的葉脈中的一個小分叉而已。

對于啃源碼這件事兒,沒有一個所謂的“一招吃遍天下”的秘訣,如果你非要讓我給出一個秘訣的話,那么就只有一句話:

啃源碼的過程,一定是非常枯燥的,特別是啃自己接觸不多的框架源碼的時候,千頭萬緒,也得下手去捋,所以一定要耐得住寂寞才行。

然后,如果你非得讓我再補充一句的話,那么就是:

調試源碼,一定要親!自!動!手!只是去看相關的文章,而沒有自己一步步的去調試源碼,那你相當于看了個寂寞。

親自動手的第一步就是搞個 Demo 出來。用“黑話”來說,這個 Demo 就是你的抓手,有了抓手你才能打出一套理論結合實際的組合拳。抓手多了,就能沉淀出可復用的方法論,最終為自己賦能。

搭建 Demo

所以,第一步肯定是先把 Demo 給搭建起來,項目結構非常的簡單,標準的三層結構:

圖片

主要是一個 Controller,一個 Service,然后搞個本地數據庫給接上,就完全夠夠的了:

圖片

Student 對象是從表里面映射過來的,隨便弄了兩個字段,主要是演示用:

圖片

就這么一點代碼,給你十分鐘,你是不是就能搭建好了?中間甚至還能摸幾分鐘魚。

要是只有這么一點東西的、極其簡單的 Demo 你都不想自己親自動手搭一下,然后自己去調試的話,僅僅是通過閱讀文章來肉眼調試,那么我只能說:

在正式開始調試代碼之前,我們還得明確一下調試的目的:想要知道 Spring 的 @Transactional 注解對于異常是否應該回滾的判斷邏輯具體是怎么樣的。

帶著問題去調試源碼,是最容易有收獲的,而且你的問題越具體,收獲越快。你的問題越籠統,就越容易在源碼里面迷失。

方法論之關注調用棧

自己 Debug 的過程就是不斷的打斷點的過程。

我再說一次:自己 Debug 的過程就是不斷的打斷點的過程。

打斷點大家都會打,斷點打在哪些地方,這個玩意就很講究了。

在我們的這個 Demo 下,第一個斷點的位置非常好判斷,就打在事務方法的入口處:

圖片

一般來說,大家調試業務代碼的時候,都是順著斷點往下調試。但是當你去閱讀框架代碼的時候,你得往回看。

什么是“往回看”呢?

當你的程序在斷點處停下的時候,你會發現 IDEA 里面有這樣的一個部分:

圖片

這個調用棧是你在調試的過程中,一個非常非常非常重要的部分。

它表示的是以當前斷點位置為終點的程序調用鏈路。

為了讓你徹底的明白這句話,我給你看一張圖:

圖片

我在 test6 方法中打上斷點,調用棧里面就是以 test6 方法為終點到 main 方法為起點的程序調用鏈接。

當你去點擊這個調用棧的時候,你會發現程序也會跟著動:

圖片

“跟著動”的這個動作,你可以理解為你站著斷點處“往回看”的過程。

當你理解了調用棧是干啥的了之后,我們再具體看看在當前的 Demo 下,這個調用棧里面都有寫啥:

圖片

標號為 ① 的地方,是 TestController 方法,也就是程序的入口。

標號為 ② 的地方,從包名稱可以看出是 String AOP 相關的方法。

標號為 ③ 的地方,就可以看到是事務相關的邏輯了。

標號為 ④ 的地方,是當前斷點處。

好,到這里,我想讓你簡單的回顧一下你來調試代碼的目的是什么?

是不是想要知道 Spring 的 @Transactional 注解對于異常是否應該回滾的判斷邏輯具體是怎么樣的。

那么,我們是不是應該主要把關注的重點放在標號為 ③ 的地方?

也就是對應到這一行:

圖片

這個地方我一定要特別的強調一下:要保持目標清晰,很多人在源碼里面迷失的原因就是不知不覺間被源碼牽著走遠了。

比如,有人看到標號為 ② 的部分,也就是 AOP 的部分,一想著這玩意我眼熟啊,書上寫過 Spring 的事務是基于 AOP 實現的,我去看看這部分代碼吧。

當你走到 AOP 里面去的時候,路就開始有點走偏了。你明白我意思吧?

即使在這個過程中,你翻閱了這部分的源碼,確實了解到了更多的關于 AOP 和事務之間的關系,但是這個部分并不解決你“關于回滾的判斷”這個問題。

然而更多更真實的情況可能是這樣的,當你點到 AOP 這部分的時候,你一看這個類名稱是 CglibAopProxy:

圖片

你一細嗦,Cglib 你也熟悉啊,它和 JDK 動態代理是一對好兄弟,都是老八股了。

然后你可能又會點擊到 AopProxy 這個接口,找到 JdkDynamicAopProxy:

圖片

接著你恍然大悟:哦,我在什么都沒有配置的情況下,當前版本的 SpringBoot 默認使用的是 Cglib 作為動態代理的實現啊。

誒,我怎么記得我背的八股文默認是使用 JDK 呢?

網上查一下,查一下。

哦,原來是這么一回事兒啊:

  • SpringBoot 1.x,默認使用的是 JDK 動態代理。
  • SpringBoot 2.x 開始,為了解決使用 JDK 動態代理可能導致的類型轉化異常而默認使用 CGLIB。
  • 在 SpringBoot 2.x 中,如果需要默認使用 JDK 動態代理可以通過配置項spring.aop.proxy-target-class=false來進行修改,proxyTargetClass配置已無效。

剛剛提到了一個 spring.aop.proxy-target-class 配置,這是個啥,咋配置啊?

查一下,查一下...

喂,醒一醒啊,朋友,走遠了啊。還記得你調試源碼的目的嗎?

如果你對于 AOP 這個部分感興趣,可以先進行簡單的記錄,但是不要去深入的追蹤。

不要覺得自己只是隨便看看,不要緊。反正正是因為這些“隨便看看”導致你在源碼里面忙了半天感覺這波學到了,但是停下來一想:我 TM 剛剛看了些啥來著?我的問題怎么還沒解決?

我為什么要把這部分非常詳盡,甚至于接近啰嗦的寫一遍,就是因為這個就是初看源碼的朋友最容易犯的錯誤。

特別強調一下:抓住主要矛盾,解決主要問題。

好,回到我們通過調用棧找到的這個和事務相關的方法中:

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

圖片

這個方法,就是我們要打第二個斷點,或者說這才是真正的第一個斷點的地方。

然后,重啟項目,重新發起請求,從這個地方就可以進行正向的調試,也就是從框架代碼一步步的往業務代碼執行。

比如這個方法接著往下 Debug,就來到了這個地方:

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

圖片

找到了這個地方,你就算是無限的接近于問題的真相了。

這個部分我肯定會講的,但是在這里先按下不表,畢竟這并不是本文最重要的東西。

本文最重要的是,我再次重申一遍:我試圖想要教會你一種閱讀源碼的方式,讓你找到一個好的切入點,或者說突破口。

由于這個案例比較簡單,所以很容易找到真正的第一個利于調試的斷點。

如果遇到一些復雜的場景、響應式的編程、異步的調用等等,可能會循環往復的執行上面的動作。

分析調用棧,打斷點,重啟。

再分析調用棧,再打斷點,再重啟。

方法論之死盯日志

其實我發現很少有人會去注意框架打印的日志,就像是很少有人會去仔細閱讀源碼上的 Javadoc 一樣。

但是其實通過觀察日志輸出,也是一個很好的尋找閱讀源碼突破口的方式。

我們要做的,就是保證 Demo 盡量的單純,不要有太多的和本次排查無關的代碼和依賴引入。

然后把日志級別修改為 debug:

logging.level.root=debug

接著,就是發起一次調用,然后耐著性子去看日志。

還是我們的這個 Demo,發起一次調用之后,控制臺輸出了很多的日志,我給你搞個縮略圖看看:

圖片

我們已知的是這里面大概率是有線索的,有沒有什么方法盡量快的找出來呢?

有,但是通用性不強。所以如果經驗不夠豐富的話,那么最好的方法就是一行行的去找。

前面我也說過了:啃源碼的過程,一定是非常枯燥的。

所以你一定會找到這樣的日志輸出:

Acquired Connection [HikariProxyConnection@982684417 wrapping com.mysql.cj.jdbc.ConnectionImpl@751a148c] for JDBC transaction
Switching JDBC Connection [HikariProxyConnection@982684417 wrapping com.mysql.cj.jdbc.ConnectionImpl@751a148c] to manual commit
...
==> Preparing: insert into student ( name, home ) values ( ?, ? )
HikariPool-1 - Pool stats (total=1, active=1, idle=0, waiting=0)
==> Parameters: why(String), 草市街199號-insertTestNoRollbackFor(String)
<== Updates: 1
...
Committing JDBC transaction on Connection [HikariProxyConnection@982684417 wrapping com.mysql.cj.jdbc.ConnectionImpl@751a148c]
Releasing JDBC Connection [HikariProxyConnection@982684417 wrapping com.mysql.cj.jdbc.ConnectionImpl@751a148c] after transaction

這幾行日志,不就是正對應著 Spring 事務的開啟和提交嗎?

有了日志,我們完全可以基于日志去找對應的日志輸出的地方,比如我們現在要找這一行日志輸出對應的代碼:

o.s.j.d.DataSourceTransactionManager     : Acquired Connection [HikariProxyConnection@982684417 wrapping com.mysql.cj.jdbc.ConnectionImpl@751a148c] for JDBC transaction

首先,我們可以根據日志知道對應輸出的類是 DataSourceTransactionManager 這個類。

然后找到這個類,按照關鍵詞搜索:

圖片

不就找到這一行代碼了嗎?

或者我們直接秉承大力出奇跡的真理,來一個暴力的全局搜索,也是能搜到這一行代碼的:

圖片

再或者修改一下日志輸出格式,把行號也搞出來嘛。

當我們把日志格式修改為這樣之后:

logging.pattern.cnotallow=%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger.%M:%L - %msg%n

控制臺的日志就變成了這樣:

org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin:263 - Acquired Connection [HikariProxyConnection@1569067488 wrapping com.mysql.cj.jdbc.ConnectionImpl@19a49539] for JDBC transaction

很直觀的就看出來了,這行日志是 DataSourceTransactionManager 類的 doBegin 方法,在 263 行輸出的。

然后你找過去,發現沒有任何毛病,這就是案發現場:

圖片

我前面給你說這么多,就是為了讓你找到這一行日志輸出的地方。

現在,找到了,然后呢?

然后肯定就是在這里打斷點,然后重啟程序,重新發起調用了啊。

這樣,你又能得到一個調用棧:

圖片

然后,你會從調用棧中看到一個我們熟悉的東西:

圖片

朋友,這不就和前面寫的“方法論之關注調用棧”呼應起來了嗎?

這不就是一套組合拳嗎,不就是沉淀出的可復用的方法論嗎?

黑話,咱們也是可以整兩句的。

方法論之查看被調用的地方

除了前面兩種方法之外,我有時候也會直接看我要閱讀部分的方法,在框架中被哪些地方調用了。

比如在我們的 Demo 中,我們要閱讀的代碼非常的明確,就是 @Transactional 注解。

于是直接看一下這個注解在哪些地方用到了:

圖片

有的時候調用的地方會非常的少,甚至只有一兩處,那么直接在調用的地方打上斷點就對了。

雖然 @Transactional 注解一眼望去也是有很多的調用,但是仔細一看大多是測試類。排除測試類、JavaDoc 里面的備注和自己項目中的使用之后,只剩下很明顯的這三處:

圖片

看起來很接近真相,但是很遺憾,這里只是在項目啟動的時候解析注解而已。和我們要調研的地方,差的還有點遠。

這個時候就需要一點經驗了,一看苗頭不對,立馬轉換思路。

什么是苗頭不對呢?

你在這幾個地方大上斷點了,只是在項目啟動的過程中斷點起作用了,發起調用的時候并沒有在斷點處停下,說明發起調用的時候并不會觸發這部分邏輯,苗頭不對。

順著這個思路想,在我的 Demo 中拋出了異常,那么 rollbackFor 和 noRollbackFor 這兩個參數大概率是會在調用的時候被用到,對吧?

圖片

所以當你去看 rollbackFor 被調用的時候只有我們自己寫的業務代碼在調用:

圖片

怎么辦呢?

這個時候就要靠一點運氣了。

是的,靠運氣。

你都點到 rollbackFor 這個方法來了,你也看了它被調用的地方,在這個過程中你大概率會瞟到幾眼它對應的 JavaDoc:

org.springframework.transaction.annotation.Transactional#rollbackFor

圖片

然后你會發現在 JavaDoc 里面提到了 rollbackOn 這個方法:

org.springframework.transaction.interceptor.DefaultTransactionAttribute.rollbackOn(Throwable)

圖片

到這里一看,你發現這是一個接口,它有好多個實現類:

圖片

怎么辦呢?

早期的時候,由于不知道具體的實現類是哪個,我是在每個實現類的入口處都打上斷點,雖然是笨辦法,但是總是能起作用的。

后來我才發現,原來可以直接在接口上打斷點:

圖片

然后,重啟項目,發起調用,第一次會停在我們方法的入口:

圖片

F9,跳過當前斷點之后,來到了這個地方:

圖片

這里就是我前面在接口上打的方法斷點,走到了這個實現類中:

org.springframework.transaction.interceptor.DelegatingTransactionAttribute

然后,關鍵的就來了,我們又有一個調用棧了,又從調用棧中看到一個我們熟悉的東西:

圖片

朋友,組合拳這不又打起來了?突破口不就又找到了?

關于“瞟到幾眼對應的 JavaDoc ,然后就可能找到突破口”的這個現象,早期對我來說確實是運氣,但是現在已經是一個習慣了。一些知名框架的 JavaDoc 真的寫的很清楚的,里面隱藏了很多關鍵信息,而且是最權威的正確信息,讀官網文檔,比讀技術博客穩當的多。

探索答案

前面我介紹的都是找到代碼調試突破口的方法。

現在突破口也有了,接下來應該怎么辦呢?

很簡單,調試,反復的調試。從這個方法開始,一步一步的調試:

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

圖片

如果你真的想要有所收獲的話,這是一個需要你親自去動手的步驟,必須要有逐行閱讀的一個過程,然后才能知道大概的處理流程。

我就不進行詳細解讀了,只是把重點給大家畫一下:

圖片

框起來的部分,就是去執行業務邏輯,然后基于業務邏輯的處理結果,去走不同的邏輯。

拋異常了,走這個方法:completeTransactionAfterThrowing

正常執行完畢了,走這個方法:commitTransactionAfterReturning

所以,我們問題的答案就藏在 completeTransactionAfterThrowing 里面。

繼續調試,進入這個方法之后,可以看到它拿到了事務和當前異常相關的信息:

圖片

在這個方法里面,大體的邏輯是當標號為 ① 的地方為 true 的時候,就在標號為 ② 的地方回滾事務,否則就在標號為 ③ 的地方提交事務:

圖片

因此,標號為 ① 的部分就很重要了,這里面就藏著我們問題的答案。

另外,在這里多說一句,在我們的案例中,這個方法,也就是當前調試的方法是不會回滾的:

圖片

而這個方法是會回滾的:

圖片

也就是這兩個方法在這個地方會走不同的邏輯,所以你在調試的時候遇到 if-else 就需要注意,去構建不同的案例,以覆蓋盡量多的代碼邏輯。

繼續往下調試,會進入到標號為 ① 的 rollbackOn 方法里面,來到這個方法:

org.springframework.transaction.interceptor.RuleBasedTransactionAttribute#rollbackOn

圖片

這里,就藏著問題的終極答案,而且這里面的代碼邏輯相對比較的繞。

核心邏輯就是通過循環 rollbackRules,這里面裝的是我們在代碼中配置的回滾規則,在循環體中拿 ex,也就是我們程序拋出的異常,去匹配規則,最后選擇一個 winner:

圖片

如果 winner 為空,則走默認邏輯。如果是 RuntimeException 或者是 Error 的子類,就要進行回滾:

圖片

如果有 winner,判斷 winner 是否是不用回滾的配置,如果是,則取反,返回 false,表示不進行回滾:

圖片

那么問題的冠軍就在于:winner 怎么來的?

答案就藏著這個遞歸調用中:

圖片

一句話描述就是:看當前拋出的異常和配置的規則中的 rollbackFor 和 noRollbackFor 誰距離更近。這里的距離指的是父類和子類之間的關系。

比如,還是這個案例:

圖片

我們拋出的是 RuntimeException,它距離 noRollbackFor=RuntimeException.class 為 0。RuntimeException 是 Exception 的子類,所以距離 rollbackFor = Exception.class 為 1。

所以,winner 是 noRollbackFor,能明白吧?

然后,我們再看一下這個案例:

圖片

根據前面的“距離”的分析,NullPointerException 是 RuntimeException 的子類,它們之間的距離是 1。而 NullPointerException 到 Exception 的距離是 2:

圖片

所以,rollbackFor=RuntimeException.class 這個的距離更短,所以 winner 是 rollbackFor。

而把 winner 放到這個判斷中,返回是 true:

return !(winner instanceof NoRollbackRuleAttribute);

所以,這就是它為什么會回滾的原因:

好了,到這里你有可能是暈的,暈就對了,去調試這部分代碼,親自摸一遍,你就搞的明明白白了。

最后,再給“死盯日志”的方法論打個補丁吧。

前面我說了,日志級別調整到 Debug 也需要會有意外發現。現在,我要再給你說一句,如果 Debug 沒有查到信息,可以試著調整到 trace:

logging.level.root=trace

比如,當我們調整到 trace 之后,就可以看到“ winner 到底是誰”這樣的信息了:

圖片

當然了,trace 級別下日志更多了。

所以,來,再跟我大聲的讀一遍:

啃源碼的過程,一定是非常枯燥的,特別是啃自己接觸不多的框架源碼的時候,千頭萬緒,也得下手去捋,所以一定要耐得住寂寞才行。

作業

我前面主要是試圖教你一種閱讀源碼時,尋找突破點的技能。這個突破點,說白了就是第一個有效的斷點到底應該打在哪里。

你用前面我教的方法,也能把 @Cacheable 和 @Async 都玩明白。因為它們的底層邏輯和 @Transactional 是一樣的。

所以,現在布置兩個作業。

拿著這套組合拳,去上手玩一玩 @Cacheable 和 @Async 吧,沉淀出屬于自己的方法論。

@Cacheable:

圖片

@Async:

圖片

本文轉載自微信公眾號「 why技術」,可以通過以下二維碼關注。轉載本文請聯系 why技術公眾號。??

??

??



責任編輯:武曉燕 來源: why技術
相關推薦

2023-11-30 08:27:38

泛化調用架構

2019-10-17 19:15:22

jQueryJavaScript前端

2023-06-21 00:10:17

JSONWeb服務器JavaScript

2021-02-19 19:35:53

SVG 形狀元素

2020-11-13 08:14:28

JavaScript

2021-07-10 10:01:37

Python簡單函數

2024-04-11 12:57:55

Python函數

2021-03-17 09:59:26

Python函數調用

2021-12-28 09:27:45

Javascript 高階函數前端

2021-03-02 18:35:27

SVG開發空間

2021-02-17 20:40:22

SVG圖像模式

2023-10-08 19:06:41

2020-02-24 21:50:24

瓶頸數據庫

2021-09-15 10:00:33

Go語言Modules

2020-12-16 08:07:28

語言基礎反射

2021-05-29 10:20:54

GoModules語言

2021-02-24 10:14:04

PythonClassPython基礎

2020-12-01 09:36:35

SVG元素屬性

2021-03-19 10:01:41

SVG畫多邊形Htm基礎

2019-01-30 13:44:34

JVM內存服務器
點贊
收藏

51CTO技術棧公眾號

亚洲国产精品av| 99视频在线精品国自产拍免费观看| 欧美日韩在线播| 色呦呦网站入口| 手机看片一区二区| 日韩激情视频在线观看| 不卡中文字幕av| 五月婷婷综合在线观看| 天堂综合在线播放| 亚洲成人激情av| 午夜成人免费电影| 亚洲一区久久久| 亚洲免费在线观看av| 日韩欧美精品| 日韩高清欧美高清| 日本精品一区在线| www.综合| 国产精品福利在线播放| 国产麻豆日韩| 国产情侣在线播放| 日韩高清不卡在线| 亚州精品天堂中文字幕| 国语对白在线播放| 精品久久91| 亚洲精品国产精品自产a区红杏吧| 亚洲成人天堂网| 亚洲黄色网址| 亚洲成av人片一区二区三区| 亚洲综合av一区| 欧美婷婷久久五月精品三区| 国产风韵犹存在线视精品| 欧美一区二区色| 国产精品成人国产乱| 亚洲激情中文| 最新91在线视频| 免费污网站在线观看| 极品尤物一区| 欧美变态口味重另类| 亚洲成人手机在线观看| 国产精品麻豆成人av电影艾秋| 欧美香蕉大胸在线视频观看 | 黄色片在线免费| av色在线观看| 香蕉成人啪国产精品视频综合网 | 欧美日韩高清在线| 欧美色图另类小说| 桃色av一区二区| 图片区小说区国产精品视频| 国产视频在线观看网站| 在线heyzo| 五月婷婷久久久| 久久av在线| 欧美中文字幕在线播放| 久久国产精品系列| 中文国产一区| 97色在线视频| 午夜毛片在线观看| 亚洲综合精品| 国产精品2018| 这里只有精品免费视频| 欧美a级一区二区| 国产精品手机播放| 亚洲一线在线观看| 极品少妇一区二区三区精品视频| 国产日韩精品在线播放| 国产精品视频久久久久久| 精品一区二区三区免费播放| 91久久精品美女| 精品人妻午夜一区二区三区四区| 国产精品一品二品| 国产伦精品一区二区三区视频黑人| 日韩中文字幕综合| 26uuu精品一区二区三区四区在线| 久久久一本精品99久久精品| 国产高清一级毛片在线不卡| 欧美极品xxx| 男同互操gay射视频在线看| 国产理论电影在线| 欧美性20hd另类| 欧美三级午夜理伦三级富婆| 国产免费区一区二区三视频免费| 精品捆绑美女sm三区| 韩国无码一区二区三区精品| 欧美三级美国一级| 久久精品男人天堂| 国产欧美日韩另类| 青青草97国产精品免费观看无弹窗版| 成人午夜黄色影院| 午夜视频在线播放| 中文字幕乱码日本亚洲一区二区 | 成人午夜电影在线播放| 香蕉视频网站在线| 国产精品成人在线观看| 欧美日韩一区精品| 国产又粗又大又爽的视频| 17videosex性欧美| 欧美日本国产视频| 久久久久成人精品无码中文字幕| 久久99国内| 欧美床上激情在线观看| 色一情一乱一伦| 国产乱妇无码大片在线观看| 玛丽玛丽电影原版免费观看1977| 免费在线观看黄色| 欧美色另类天堂2015| av中文字幕网址| 香蕉久久99| 久久国产精品久久久| 国产又黄又猛又粗又爽| 国产精品一区二区久久精品爱涩| 欧美亚洲另类久久综合| 欧美卡一卡二| 91精品中文字幕一区二区三区| 国产一级黄色录像| 亚洲国产精品久久久天堂| 日韩男女性生活视频| 亚洲第九十九页| 成人欧美一区二区三区视频网页| 免费黄色福利视频| 福利片一区二区| 久久这里只有精品视频首页| 老熟妇一区二区三区| 成a人片亚洲日本久久| 中文字幕在线乱| av成人在线播放| 亚洲激情视频在线播放| 久久久久久久中文字幕| 国内精品伊人久久久久av一坑| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 欧美一二区视频| 长河落日免费高清观看| 久久人人超碰| 欧美不卡在线一区二区三区| bl视频在线免费观看| 欧美一二三四在线| 国产高潮国产高潮久久久91| 久久国产麻豆精品| 日韩.欧美.亚洲| 国产精品专区免费| 在线成人超碰| 日本精品久久久久影院| 性xxxxbbbb| 偷拍亚洲欧洲综合| 国产一级黄色录像| 亚洲人人精品| 黑人巨大精品欧美一区二区小视频 | 国产主播一区二区| 一区二区av| 亚洲国产一区二区久久| 久久激情视频免费观看| 亚洲图片视频小说| 国产精品高潮呻吟| 毛片毛片毛片毛片毛| 中文精品电影| 9a蜜桃久久久久久免费| 亚洲妇熟xxxx妇色黄| 日韩欧美亚洲另类制服综合在线| 麻豆亚洲av熟女国产一区二 | 91视频免费进入| 中文字幕中文字幕在线中高清免费版| 欧美一区二区网站| 免费中文字幕在线观看| 不卡一区二区三区四区| 成人av一级片| 精品一区二区三| 国产女同一区二区| 五月天激情在线| 精品国产91久久久久久久妲己| 国产无遮挡又黄又爽| 久久综合一区二区| 亚洲欧美在线精品| 天天色综合色| 国产精品免费看一区二区三区| 成人爽a毛片免费啪啪动漫| 日韩高清a**址| 亚洲图片小说视频| 亚洲一区二区三区精品在线| 国产人妻人伦精品1国产丝袜| 日韩中文字幕av电影| 一区二区高清视频| 国产精品对白| 国产精品www色诱视频| 丝袜美腿美女被狂躁在线观看| 欧美一区二区精品在线| 亚洲黄色三级视频| 国产精品久久国产精麻豆99网站| 丰满人妻一区二区三区53视频| 中文在线一区| 91麻豆成人久久精品二区三区| 一级特黄妇女高潮| 欧美激情极品| 国产在线久久久| xxxx另类黑人| 色吧影院999| 色屁屁草草影院ccyycom| 欧美性一级生活| 久久久久久久国产精品毛片| 2020国产精品| 亚洲精品成人无码毛片| 日韩精品1区2区3区| 黑人巨茎大战欧美白妇| 在线成人动漫av| 99理论电影网| 欧洲精品久久久久毛片完整版| 久久久之久亚州精品露出| jyzzz在线观看视频| 精品盗摄一区二区三区| 亚洲一区 中文字幕| 婷婷开心久久网| 农村黄色一级片| 国产精品色哟哟| 51调教丨国产调教视频| 国产精品一区久久久久| av五月天在线| 一本色道精品久久一区二区三区| 一区在线电影| 精品国精品国产自在久国产应用 | 91国内在线播放| 亚洲影音一区| 妺妺窝人体色777777| 99久久久国产精品美女| 青青成人在线| 日韩激情网站| 国产精品久久国产精品| 国产精品va视频| 国产男女猛烈无遮挡91| 日韩一区二区三区免费| …久久精品99久久香蕉国产| 欧洲性视频在线播放| 久久精品国产久精国产一老狼| 国产三级视频在线| 亚洲片在线资源| 飘雪影院手机免费高清版在线观看| 欧美不卡一二三| av网站在线免费看| 欧美一级理论片| 国产精品爽爽久久久久久| 欧美日韩美女一区二区| 五月激情丁香网| 欧洲精品一区二区| 91丨九色丨海角社区| 麻豆精品蜜桃视频网站| 无码播放一区二区三区| 一区二区自拍| 国产肉体ⅹxxx137大胆| 欧美不卡高清| 欧洲精品视频在线| 自拍偷拍欧美| 日日噜噜夜夜狠狠久久丁香五月| 久久高清精品| 性色av一区二区三区在线观看 | 精品影院一区| 精品一区二区电影| 欧美色视频免费| 亚洲全黄一级网站| 国产私人尤物无码不卡| 国产一区二区三区四区福利| h视频在线免费| www.日韩免费| 日韩少妇视频| 97香蕉超级碰碰久久免费软件| 中日韩脚交footjobhd| 日韩美女免费观看| 国产精品久久久久久妇女| 国产区亚洲区欧美区| 电影一区二区三区久久免费观看| 91精品视频免费观看| 亚洲精品v亚洲精品v日韩精品| 国产高清自拍一区| 亚洲香蕉视频| 一区二区三区在线观看www| 亚洲欧美在线专区| 18禁裸男晨勃露j毛免费观看| 亚洲区国产区| 九九视频精品在线观看| 国产真实乱对白精彩久久| av免费观看不卡| 国产日韩一级二级三级| 亚洲天堂网av在线| 亚洲一区二区三区四区五区中文| 国产情侣自拍av| 91国产免费看| aa视频在线免费观看| 亚洲精品按摩视频| 日本三级在线播放完整版| 欧美激情女人20p| 日韩成人影音| 91亚洲精品丁香在线观看| 亚洲人和日本人hd| www.午夜色| 国产精品久久777777毛茸茸| 91国内在线播放| 91麻豆国产精品久久| 91制片厂在线| 高跟丝袜一区二区三区| 国产一区二区小视频| 亚洲精品动漫100p| 亚洲免费视频一区二区三区| 欧美激情在线视频二区| av免费在线一区| 国产精品12| 久久综合国产| 日韩av黄色网址| 国产乱国产乱300精品| www.av天天| 五月激情综合色| av天堂一区二区三区| 国产香蕉精品视频一区二区三区| 26uuu亚洲电影在线观看| 国产黑人绿帽在线第一区| 日本成人精品| 亚洲午夜在线观看| 香蕉亚洲视频| 无码人妻一区二区三区一| 日本一区二区三区视频视频| 黄色激情视频在线观看| 91精品国产一区二区| 成人性生交大片免费看午夜| 性欧美视频videos6一9| 久久wwww| 亚洲一区综合| 日韩av不卡在线观看| 亚洲欧美日本一区| 一片黄亚洲嫩模| 国产精品永久久久久久久久久| 尤物精品国产第一福利三区 | 国产精品视频色| 亚洲图片久久| 国产美女三级视频| 不卡的av网站| 国产一级做a爰片在线看免费| 欧美精品vⅰdeose4hd| av片在线免费观看| 国产精品久久激情| 欧美精选一区二区三区| 热久久精品国产| 久久综合久久99| 9i看片成人免费看片| 亚洲精品国产精品久久清纯直播| 高清电影在线观看免费| 粉嫩av一区二区三区免费观看| 午夜国产欧美理论在线播放| 欧美成人手机在线视频| 国产精品久久久久久久久久免费看 | 91精品国产自产在线观看永久| 不卡中文字幕| 在线黄色免费观看| 中文字幕一区二区三区不卡 | 国产一级aa大片毛片| 日韩三区在线观看| 性欧美1819sex性高清大胸| 亚洲xxxxx性| 国产精品vip| 免费的av网站| 日韩欧美国产中文字幕| 狠狠狠综合7777久夜色撩人 | 999久久精品| 免费无码毛片一区二三区| av日韩在线网站| 男人天堂av在线播放| 一区二区av在线| 欧美男男gaygay1069| 精品日韩在线播放| 成人动漫一区二区在线| 91午夜视频在线观看| 亚洲天堂av在线免费| 玖玖精品在线| 精品无码av无码免费专区| 成人禁用看黄a在线| 成年人视频在线免费看| 国产亚洲综合久久| 高清不卡一区| 六月婷婷在线视频| 国产欧美日韩精品一区| 国产美女永久免费| 久久免费福利视频| 国产影视精品一区二区三区| 亚洲欧美日本一区二区| 亚洲第一福利一区| 黄色在线播放| 91在线免费看网站| 亚洲精选在线| 久久久久99精品成人| 亚洲精品一区二区三区影院| 欧美日韩123区| 久久久久亚洲av无码专区喷水| 成人小视频免费观看| 国产主播第一页| 欧美巨乳美女视频| 精品国产一区二区三区| 亚洲在线观看网站| 欧美性生交大片免网| 黄色网页在线免费观看| 久久九九视频| 国产一区二三区| 秋霞精品一区二区三区| 欧美肥婆姓交大片| 不卡av一区二区| 国产精品一区二区人妻喷水| 在线一区二区三区四区五区|