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

為啥一個 Main 方法就能啟動項目

開發 架構
在 IDE 中也需要對 Web 容器進行一些配置,才能夠運行或者 Debug。而使用 Spring Boot 我們只需要像運行普通 JavaSE 程序一樣,run 一下 main() 方法就可以啟動一個 Web 應用了。這是怎么做到的呢?今天我們就一探究竟,分析一下 Spring Boot 的啟動流程。

在 Spring Boot 出現之前,我們要運行一個 Java Web 應用,首先需要有一個 Web 容器(例如 Tomcat 或 Jetty),然后將我們的 Web 應用打包后放到容器的相應目錄下,最后再啟動容器。

在 IDE 中也需要對 Web 容器進行一些配置,才能夠運行或者 Debug。而使用 Spring Boot 我們只需要像運行普通 JavaSE 程序一樣,run 一下 main() 方法就可以啟動一個 Web 應用了。這是怎么做到的呢?今天我們就一探究竟,分析一下 Spring Boot 的啟動流程。

概覽

回看我們寫的第一個 Spring Boot 示例,我們發現,只需要下面幾行代碼我們就可以跑起一個 Web 服務器:

@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}

去掉類的聲明和方法定義這些樣板代碼,核心代碼就只有一個 @SpringBootApplication 注解和 SpringApplication.run(HelloApplication.class, args) 了。而我們知道注解相當于是一種配置,那么這個 run() 方法必然就是 Spring Boot 的啟動入口了。

接下來,我們沿著 run() 方法來順藤摸瓜。進入 SpringApplication 類,來看看 run() 方法的具體實現:

public class SpringApplication {
......
public ConfigurableApplicationContext run(String... args) {
// 1 應用啟動計時開始
StopWatch stopWatch = new StopWatch();
stopWatch.start();

// 2 聲明上下文
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;

// 3 設置 java.awt.headless 屬性
configureHeadlessProperty();

// 4 啟動監聽器
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 5 初始化默認應用參數
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

// 6 準備應用環境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);

// 7 打印 Banner(Spring Boot 的 LOGO)
Banner printedBanner = printBanner(environment);

// 8 創建上下文實例
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);

// 9 構建上下文
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);

// 10 刷新上下文
refreshContext(context);

// 11 刷新上下文后處理
afterRefresh(context, applicationArguments);

// 12 應用啟動計時結束
stopWatch.stop();
if (this.logStartupInfo) {
// 13 打印啟動時間日志
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}

// 14 發布上下文啟動完成事件
listeners.started(context);

// 15 調用 runners
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// 16 應用啟動發生異常后的處理
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}


try {
// 17 發布上下文就緒事件
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
......
}

Spring Boot 啟動時做的所有操作都這這個方法里面,當然在調用上面這個 run() 方法之前,還創建了一個 SpringApplication 的實例對象。因為上面這個 run() 方法并不是一個靜態方法,所以需要一個對象實例才能被調用。

可以看到,方法的返回值類型為
ConfigurableApplicationContext,這是一個接口,我們真正得到的是 AnnotationConfigServletWebServerApplicationContext 的實例。通過類名我們可以知道,這是一個基于注解的 Servlet Web 應用上下文(我們知道上下文(context)是 Spring 中的核心概念)。

上面對于 run() 方法中的每一個步驟都做了簡單的注釋,接下來我們選擇幾個比較有代表性的來詳細分析。

應用啟動計時

在 Spring Boot 應用啟動完成時,我們經常會看到類似下面內容的一條日志:

Started AopApplication in 2.732 seconds (JVM running for 3.734)

應用啟動后,會將本次啟動所花費的時間打印出來,讓我們對于啟動的速度有一個大致的了解,也方便我們對其進行優化。記錄啟動時間的工作是 run() 方法做的第一件事,在編號 1 的位置由 stopWatch.start() 開啟時間統計,具體代碼如下:

public void start(String taskName) throws IllegalStateException {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");
}
// 記錄啟動時間
this.currentTaskName = taskName;
this.startTimeNanos = System.nanoTime();
}

然后到了 run() 方法的基本任務完成的時候,由 stopWatch.stop()(編號 12 的位置)對啟動時間做了一個計算,源碼也很簡單:

public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
}
// 計算啟動時間
long lastTime = System.nanoTime() - this.startTimeNanos;
this.totalTimeNanos += lastTime;
......
}

最后,在 run() 中的編號 13 的位置將啟動時間打印出來:

if (this.logStartupInfo) {
// 打印啟動時間
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}

打印 Banner

Spring Boot 每次啟動是還會打印一個自己的 LOGO,如圖 8-6:

圖 8-6 Spring Boot Logo

這種做法很常見,像 Redis、Docker 等都會在啟動的時候將自己的 LOGO 打印出來。Spring Boot 默認情況下會打印那個標志性的“樹葉”和 “Spring” 的字樣,下面帶著當前的版本。

在 run() 中編號 7 的位置調用打印 Banner 的邏輯,最終由 SpringBootBanner 類的 printBanner() 完成。這個圖案定義在一個常量數組中,代碼如下:

class SpringBootBanner implements Banner {
private static final String[] BANNER = {
"",
" . ____ _ __ _ _",
" /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\",
"( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
" \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )",
" ' |____| .__|_| |_|_| |_\\__, | / / / /",
" =========|_|==============|___/=/_/_/_/"
};
......

public void printBanner(Environment environment, Class<?> sourceClass, PrintStream printStream) {
for (String line : BANNER) {
printStream.println(line);
}
......
}
}

手工格式化了一下 BANNER 的字符串,輪廓已經清晰可見了。真正打印的邏輯就是 printBanner() 方法里面的那個 for 循環。

記錄啟動時間和打印 Banner 代碼都非常的簡單,而且都有很明顯的視覺反饋,可以清晰的看到結果。拿出來咱們做個熱身,配合斷點去 Debug 會有更加直觀的感受,尤其是打印 Banner 的時候,可以看到整個內容被一行一行打印出來,讓我想起了早些年用那些配置極低的電腦(還是 CRT 顯示器)運行著 Win98,經常會看到屏幕內容一行一行加載顯示。

創建上下文實例

下面我們來到 run() 方法中編號 8 的位置,這里調用了一個 createApplicationContext() 方法,該方法最終會調用 ApplicationContextFactory 接口的代碼:

ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch (webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
+ "you may need a custom ApplicationContextFactory", ex);
}
};

這個方法就是根據 SpringBootApplication 的 webApplicationType 屬性的值,利用反射來創建不同類型的應用上下文(context)。而屬性 webApplicationType 的值是在前面執行構造方法的時候由
WebApplicationType.deduceFromClasspath() 獲得的。通過方法名很容易看出來,就是根據 classpath 中的類來推斷當前的應用類型。

我們這里是一個普通的 Web 應用,所以最終返回的類型為 SERVLET。所以會返回一個
AnnotationConfigServletWebServerApplicationContext 實例。

構建容器上下文

接著我們來到 run() 方法編號 9 的 prepareContext() 方法。通過方法名,我們也能猜到它是為 context 做上臺前的準備工作的。

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
......
// 加載資源
load(context, sources.toArray(new Object[0]));
listeners.contextLoaded(context);
}

在這個方法中,會做一些準備工作,包括初始化容器上下文、設置環境、加載資源等。

加載資源

上面的代碼中,又調用了一個很關鍵的方法——load()。這個 load() 方法真正的作用是去調用 BeanDefinitionLoader 類的 load() 方法。源碼如下:

class BeanDefinitionLoader {
......
void load() {
for (Object source : this.sources) {
load(source);
}
}
private void load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class<?>) {
load((Class<?>) source);
return;
}
if (source instanceof Resource) {
load((Resource) source);
return;
}
if (source instanceof Package) {
load((Package) source);
return;
}
if (source instanceof CharSequence) {
load((CharSequence) source);
return;
}
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
......
}

可以看到,load() 方法在加載 Spring 中各種資源。其中我們最熟悉的就是 load((Class<?>) source) 和 load((Package) source) 了。一個用來加載類,一個用來加載掃描的包。

load((Class<?>) source) 中會通過調用 isComponent() 方法來判斷資源是否為 Spring 容器管理的組件。isComponent() 方法通過資源是否包含 @Component 注解(@Controller、@Service、@Repository 等都包含在內)來區分是否為 Spring 容器管理的組件。

而 load((Package) source) 方法則是用來加載 @ComponentScan 注解定義的包路徑。

刷新上下文

run() 方法編號10 的 refreshContext() 方法是整個啟動過程比較核心的地方。像我們熟悉的 BeanFactory 就是在這個階段構建的,所有非懶加載的 Spring Bean(@Controller、@Service 等)也是在這個階段被創建的,還有 Spring Boot 內嵌的 Web 容器要是在這個時候啟動的。

跟蹤源碼你會發現內部調用的是
ConfigurableApplicationContext.refresh(),ConfigurableApplicationContext 是一個接口,真正實現這個方法的有三個類:AbstractApplicationContext、ReactiveWebServerApplicationContext 和 ServletWebServerApplicationContext。

AbstractApplicationContext 為后面兩個的父類,兩個子類的實現比較簡單,主要是調用父類實現,比如 ServletWebServerApplicationContext 中的實現是這樣的:

public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}

主要的邏輯都在AbstractApplicationContext 中:

@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 1 準備將要刷新的上下文
prepareRefresh();
// 2 (告訴子類,如:ServletWebServerApplicationContext)刷新內部 bean 工廠
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3 為上下文準備 bean 工廠
prepareBeanFactory(beanFactory);
try {
// 4 允許在子類中對 bean 工廠進行后處理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 5 調用注冊為 bean 的工廠處理器
invokeBeanFactoryPostProcessors(beanFactory);
// 6 注冊攔截器創建的 bean 處理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 7 初始化國際化相關資源
initMessageSource();
// 8 初始化事件廣播器
initApplicationEventMulticaster();
// 9 為具體的上下文子類初始化特定的 bean
onRefresh();
// 10 注冊監聽器
registerListeners();
// 11 實例化所有非懶加載的單例 bean
finishBeanFactoryInitialization(beanFactory);
// 12 完成刷新發布相應的事件(Tomcat 就是在這里啟動的)
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 遇到異常銷毀已經創建的單例 bean
destroyBeans();
// 充值 active 標識
cancelRefresh(ex);
// 將異常向上拋出
throw ex;
} finally {
// 重置公共緩存,結束刷新
resetCommonCaches();
contextRefresh.end();
}
}
}

簡單說一下編號 9 處的 onRefresh() 方法,該方法父類未給出具體實現,需要子類自己實現,ServletWebServerApplicationContext 中的實現如下:

protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
private void createWebServer() {
......
if (webServer == null && servletContext == null) {
......
// 根據配置獲取一個 web server(Tomcat、Jetty 或 Undertow)
ServletWebServerFactory factory = getWebServerFactory();
this.webServer = factory.getWebServer(getSelfInitializer());
......
}
......
}

factory.getWebServer(getSelfInitializer()) 會根據項目配置得到一個 Web Server 實例,這里跟下一篇將要談到的自動配置有點關系。

責任編輯:姜華 來源: 今日頭條
相關推薦

2011-09-19 16:47:18

vista

2025-11-07 01:43:00

2021-10-19 18:22:50

Map 注冊表源碼

2024-02-19 00:21:45

開源圖片

2021-11-23 23:01:40

Windows微軟系統

2019-05-27 08:29:32

啟動項目PMP

2021-04-08 09:49:49

MySQL索引數據庫

2019-12-24 11:00:51

FedoraLive CD系統運維

2015-07-29 10:00:16

開源項目

2014-10-21 10:25:50

程序員

2017-06-20 14:29:12

Rec開源項目

2014-03-31 10:20:12

2020-08-17 15:25:25

HTMLPython網頁

2019-04-30 09:05:16

項目啟動PMP

2013-03-08 02:52:03

個人開發項目糾錯

2016-01-05 13:52:05

Kotlin掌握語言

2018-10-28 17:28:48

2017-03-06 10:01:52

2025-03-03 00:00:55

Spring文件下載開發

2009-05-08 09:32:27

JavaWeb編程框架
點贊
收藏

51CTO技術棧公眾號

成人精品在线观看视频| 黄色一级视频在线播放| 一级片一区二区三区| 88国产精品视频一区二区三区| 欧美一区二区三区公司| 日韩精品 欧美| 在线a人片免费观看视频| 国产91精品露脸国语对白| 日本欧美国产在线| 日本高清一二三区| 蜜臀91精品国产高清在线观看| 欧美精品成人一区二区三区四区| 男人日女人视频网站| 999国产在线视频| 9久草视频在线视频精品| 国产精品入口夜色视频大尺度| 欧美日韩免费做爰视频| re久久精品视频| 亚洲国产精品久久精品怡红院| 亚洲免费看av| 午夜不卡影院| 亚洲综合一二三区| 亚洲一区三区| 国产尤物视频在线| 99麻豆久久久国产精品免费| 成人午夜黄色影院| 免费黄色片视频| 亚洲激情专区| 欧美激情久久久久| 很污很黄的网站| 久久99性xxx老妇胖精品| 精品久久一区二区三区| 在线免费看v片| 成人在线视频观看| 色哟哟国产精品免费观看| 欧美这里只有精品| 最新黄网在线观看| 亚洲视频网在线直播| 婷婷四月色综合| 国产在线免费观看| 久久久精品国产免大香伊 | 一区二区三区日本视频| 色狠狠色狠狠综合| 国产欧美高清在线| 亚洲黄色网址| 精品免费在线视频| 男女超爽视频免费播放| segui88久久综合9999| 一区二区三区四区中文字幕| 自拍另类欧美| 免费网站看v片在线a| 国产精品你懂的| 亚洲一区三区视频在线观看| 色多多视频在线观看| 国产精品丝袜一区| 亚洲欧美日韩不卡一区二区三区| 二区三区在线播放| 中文字幕第一页久久| 天天综合色天天综合色hd| 国产裸舞福利在线视频合集| 国产视频一区二区在线| 神马影院一区二区| 在线免费观看的av网站| 中文字幕制服丝袜成人av| 国产成年人在线观看| 国产区在线看| 亚洲一区二区在线观看视频| 日本欧美视频在线观看| 亚洲美女尤物影院| 欧美在线观看视频一区二区三区 | 精品一区二区三区香蕉蜜桃| 国产精品视频网站| 国产影视一区二区| 国产一区二区在线看| 超碰97在线人人| 色婷婷av一区二区三| 91玉足脚交白嫩脚丫在线播放| 久久精品99久久| 二区三区在线| 亚洲免费在线播放| 成人黄色大片网站| 伊人久久视频| 欧美人狂配大交3d怪物一区| 中文字幕第六页| 久草在线综合| 中文欧美在线视频| 免费在线黄色网| 99国产精品99久久久久久粉嫩| 国产91在线播放精品91| 一级黄色短视频| 成人午夜电影网站| 色女孩综合网| 四虎影视成人| 在线观看亚洲成人| 国产成人精品综合久久久久99| 欧美精品中文| 综合国产在线观看| xxxx 国产| 老牛嫩草一区二区三区日本| 国产精品久久久久高潮| 波多野结衣一区二区三区在线 | 国产精品免费网站| www.超碰在线.com| 99久久伊人久久99| 日本日本精品二区免费| 黄视频在线免费看| 欧美日韩精品欧美日韩精品| www.国产视频.com| 亚洲成a人片77777在线播放| 久久夜色精品国产| 欧美一级视频免费观看| 国产一区二区三区日韩| caoporen国产精品| 邻家有女韩剧在线观看国语| 一区二区三区免费网站| 91插插插插插插插插| 精品五月天堂| 久久影院中文字幕| 欧美另类高清videos的特点| 99久久婷婷国产精品综合| 欧美xxxx吸乳| 欧美a视频在线| 亚洲欧美精品一区| 日韩少妇裸体做爰视频| 国产一区亚洲一区| 亚洲精品成人自拍| 国产日韩另类视频一区| 亚洲精品suv精品一区二区| 黄色香蕉视频在线观看| 日韩av网站在线观看| 欧美精品国产精品久久久| 波多野结衣在线播放| 日韩欧美一级片| 日韩va亚洲va欧美va清高| 美女视频黄久久| 亚洲精蜜桃久在线| 久久99国产精品二区高清软件| 亚洲人成网站色ww在线| 中文字幕第四页| 91在线视频在线| 免费观看日韩毛片| 欧美a大片欧美片| 久久久久久久一区二区| 欧美自拍偷拍第一页| 亚洲午夜影视影院在线观看| 久草福利在线观看| 国产精品二区影院| 国产精品毛片va一区二区三区| 午夜小视频在线观看| 日韩视频国产视频| 免费人成年激情视频在线观看| 国产尤物一区二区在线| 天堂а√在线中文在线| 精品国产第一国产综合精品| www.精品av.com| 国产免费av电影| 亚洲精品第1页| 台湾佬美性中文| 99精品欧美| 秋霞久久久久久一区二区| 肉色欧美久久久久久久免费看| 亚洲人成免费电影| 中文字幕第一页在线播放| 中文字幕一区二区三区在线观看 | 国产成人在线视频网站| 日韩人妻无码精品久久久不卡| 国产亚洲成av人片在线观黄桃| 97精品国产97久久久久久春色| 日本亚洲欧美| 欧美性大战xxxxx久久久| 2025国产精品自拍| 成人教育av在线| 成人在线看视频| 久久久影院免费| 91av免费看| 欧亚在线中文字幕免费| 中文字幕精品www乱入免费视频| 国产精品永久久久久久久久久| 玉米视频成人免费看| 三级男人添奶爽爽爽视频| 免费成人性网站| 欧美乱做爰xxxⅹ久久久| 在线亚洲a色| 亚洲free性xxxx护士白浆| 多野结衣av一区| 最近2019年日本中文免费字幕| 亚洲a视频在线观看| 日韩欧美中文字幕在线播放| 糖心vlog免费在线观看| 99re热这里只有精品视频| 午夜免费福利视频在线观看| 欧美日韩天堂| 亚洲精品久久区二区三区蜜桃臀| 午夜视频在线观看精品中文| 欧美在线视频导航| 国产在线观看a| 国产午夜精品美女视频明星a级| 国产精品国产三级国产aⅴ| 香蕉久久一区二区不卡无毒影院 | 婷婷亚洲五月| 久久久久高清| 久久久久九九精品影院| 国产999视频| av中文在线资源库| 久久色免费在线视频| 黄色av网址在线免费观看| 欧美va亚洲va| 国产精品久久久国产盗摄| 欧美午夜视频一区二区| 精品97人妻无码中文永久在线 | 亚洲黄色有码视频| 91好色先生tv| 91久久精品一区二区二区| 国产在线一二区| 亚洲日本在线观看| 91精品久久久久久久久久久久| 成人久久视频在线观看| 三级一区二区三区| 日本不卡一二三区黄网| 精品这里只有精品| 尤物在线精品| 青青草原网站在线观看| 日韩毛片视频| 日韩欧美国产二区| 久久不见久久见国语| 精品毛片久久久久久| 国产精品午夜av| av一区二区三区四区电影| 91亚洲精品在看在线观看高清| 国产成人拍精品视频午夜网站| 3344国产永久在线观看视频| 色与欲影视天天看综合网| 成人免费网址| 免费av一区二区| 九义人在线观看完整免费版电视剧| 亚洲人成网在线播放| 久久精品色图| 亚洲精品自拍第一页| 国产熟女一区二区三区四区| 5858s免费视频成人| 中国女人一级一次看片| 日本韩国欧美一区| 一级黄色在线观看| 欧美亚洲自拍偷拍| 久草热在线观看| 欧美日韩国产在线观看| 91美女精品网站| 欧美福利视频导航| 中文字幕人妻精品一区| 欧美三级视频在线观看| 中文字幕资源网| 制服丝袜在线91| 午夜免费福利视频| 亚洲成色777777女色窝| 偷拍自拍在线| 亚洲女人天堂色在线7777| 国模吧精品人体gogo| 中文字幕精品一区久久久久 | 九九热精品视频在线观看| 欧美三级网色| 91嫩草亚洲精品| 久久久天堂国产精品| 在线精品观看| 男女视频一区二区三区| 精品一区精品二区高清| 欧美人与性动交α欧美精品| 成人短视频下载| 欧洲美一区二区三区亚洲| 国产精品成人免费精品自在线观看| 国产精品成人69xxx免费视频| 亚洲精品国产a| 国产高清中文字幕| 欧美日韩一区二区三区视频| 99久久精品免费看国产交换| 亚洲电影在线观看| 国内精品一区视频| 久久99精品视频一区97| 欧美一级鲁丝片| 91色中文字幕| 欧美天堂影院| 自拍另类欧美| 在线午夜精品| 日本国产一级片| 91日韩在线专区| 91人妻一区二区三区蜜臀| 午夜精品福利一区二区三区蜜桃| 国内av在线播放| 亚洲第一av在线| 日本在线观看网站| 午夜精品一区二区三区视频免费看| 欧美日韩精品一区二区三区视频| 亚洲自拍偷拍色片视频| 免费欧美一区| 男人添女荫道口女人有什么感觉| 久久电影一区| 2018国产精品| 国产精品免费视频观看| 日本一级淫片色费放| 欧美日韩一区小说| 日本中文字幕电影在线观看| 久久成人亚洲精品| 成人做爰免费视频免费看| www.久久久| 91嫩草亚洲精品| 国产一级不卡毛片| av电影在线观看不卡| 欧美三级免费看| 欧美日韩国产精选| 欧美日韩免费做爰大片| 欧美极品少妇全裸体| www.久久热| 亚洲制服欧美久久| 天堂影院一区二区| www.日本高清| 亚洲一二三区不卡| 国产青青草视频| 日韩资源在线观看| 欧美暴力调教| 欧美日本亚洲| 香蕉国产精品偷在线观看不卡| 熟女人妻一区二区三区免费看| 日韩理论片一区二区| 最近国语视频在线观看免费播放| 日韩激情在线视频| 成年人在线网站| 国产精品久久久久免费| 欧美日本在线| 免费观看黄网站| 亚洲免费在线观看视频| 97caocao| 久久精品国产免费观看| 久久av日韩| www.午夜色| 激情欧美日韩一区二区| 亚洲欧美精品久久| 91福利在线导航| 岛国在线大片| 国产精品久久在线观看| 精品国产91久久久久久浪潮蜜月| 人妻有码中文字幕| 久久久久久久久久看片| 国产一级淫片a视频免费观看| 亚洲免费精彩视频| 国产免费不卡| 日韩精彩视频| 久久一区亚洲| 欧美午夜激情影院| 欧美日韩一区二区在线观看| 午夜在线小视频| 成人欧美在线观看| 欧美精品大片| 男人网站在线观看| 香港成人在线视频| 色丁香婷婷综合久久| 欧洲一区二区视频| 欧美一区二区三| 一区二区在线免费看| 亚洲天堂精品在线观看| www.精品久久| 97免费视频在线| 免费观看久久av| 天美星空大象mv在线观看视频| 国产精品美女久久久久高潮| 91丨porny丨在线中文 | 美女高潮久久久| 国产成人综合在线视频| 精品国产伦一区二区三区观看体验| 波多野结衣精品| 日韩av在线电影观看| 久久99精品一区二区三区三区| 欧美在线视频第一页| 亚洲成年人在线播放| 韩国久久久久久| 中文字幕欧美日韩一区二区三区 | 蜜桃av免费观看| 日韩欧美国产系列| 一个人看的www视频在线免费观看| 欧美精品一区在线| 国产在线精品不卡| 国产无套丰满白嫩对白| 久久久精品国产网站| 欧美1区2区3区4区| 污视频网址在线观看| 婷婷久久综合九色综合伊人色| www.在线视频.com| 国产乱码精品一区二区三区日韩精品| 久久亚洲二区| 91高清免费看| 亚洲视频精品在线| 久久爱www.| 热久久精品免费视频| 亚洲精品欧美激情| 国产香蕉在线| 成人性色av| 久久 天天综合| 日韩av电影网| 久久久极品av| 精品视频黄色| 黄色av网址在线观看| 91精品国产综合久久小美女|