成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識(shí)庫 > 詳解從源碼分析tomcat如何調(diào)用Servlet的初始化

詳解從源碼分析tomcat如何調(diào)用Servlet的初始化

熱門標(biāo)簽:怎么找到?jīng)]有地圖標(biāo)注的店 打400電話怎么辦理收費(fèi) 河南防封號(hào)電銷機(jī)器人是什么 麗江真人語音電話外呼系統(tǒng) 福州企業(yè)電銷機(jī)器人排名 上海申請(qǐng)高400開頭的電話 宿城區(qū)電話機(jī)器人找哪家 10086外包用的什么外呼系統(tǒng) 400電話辦理介紹信

引言

上一篇博客我們將tomcat源碼在本地成功運(yùn)行了,所以在本篇博客中我們從源碼層面分析,tomcat在啟動(dòng)的過程中,是如何初始化servlet容器的。我們平常都是將我們的服務(wù)部署到 tomcat中,然后修改一下配置文件,啟動(dòng)就可以對(duì)外提供 服務(wù)了,但是我們對(duì)于其中的一些流程并不是非常的了解,例如如何加載的web.xml等。這是我們分析servlet 和 sringMVC必不可少的過程。

注釋源碼地址:https://github.com/good-jack/tomcat_source/tree/master

一、代碼啟動(dòng)tomcat

平常我們不論是Windows還是linux,我們都是通過腳本來啟動(dòng)tomcat,這對(duì)于我們分析源碼不是很友好,所以我們 需要通過代碼啟動(dòng),啟動(dòng)代碼如下:

Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        //new 出各層容器,并且維護(hù)各層容器的關(guān)系
        tomcat.addWebapp("/","/");
        tomcat.start();
        //阻塞監(jiān)聽端口
        tomcat.getServer().await();

啟動(dòng)代碼還是非常非常簡(jiǎn)單,從代碼中我們就可以看出,我們本篇博客主要分析的就是 addWebapp()方法和start()方法,通過這兩個(gè)方法我們就可以找到servlet容器是在什么時(shí)候被初始化的。

二、tomcat框架

在我們進(jìn)行分析上面兩個(gè)方法之前,我們先總結(jié)一下tomcat的基礎(chǔ)框架,其實(shí)從我們非常熟悉的 server.xml配置文件中就可以知道,tomcat就是一系列父子容器組成:

Server ---> Service --> Connector Engine addChild---> context(servlet容器) ,這就是我們從配置文件中分析出來的幾個(gè)容器,tomcat啟動(dòng)時(shí)候就是逐層啟動(dòng)容器。

三、創(chuàng)建容器(addWebapp())

3.1 方法 調(diào)用流程圖

上面的流程圖就是,從源碼中逐步分析出來的幾個(gè)重要的方法,這對(duì)于我們分析源碼非常有幫助。

3.2 源碼分析

1)通過反射獲得configContext監(jiān)聽器

方法路徑:package org.apache.catalina.startup.Tomcat.addWebapp(Host host, String contextPath, String docBase);

 
    public Context  addWebapp(Host host, String contextPath, String docBase) {
        //通過反射獲得一個(gè)監(jiān)聽器  ContextConfig,
        //通過反射得到的一定是LifecycleListener的一個(gè)實(shí)現(xiàn)類,進(jìn)入getConfigClass得到實(shí)現(xiàn)類(org.apache.catalina.startup.ContextConfig)
        LifecycleListener listener = null;
        try {
            Class<?> clazz = Class.forName(getHost().getConfigClass());
            listener = (LifecycleListener) clazz.getConstructor().newInstance();
        } catch (ReflectiveOperationException e) {
            // Wrap in IAE since we can't easily change the method signature to
            // to throw the specific checked exceptions
            throw new IllegalArgumentException(e);
        }
 
        return addWebapp(host, contextPath, docBase, listener);
    }

2) 獲得一個(gè)context容器(StandardContext)

在下面代碼中,createContext()方法通過反射加載StandardContext容器,并且將設(shè)置監(jiān)聽ContextConfig, ctx.addLifecycleListener(config);

public Context addWebapp(Host host, String contextPath, String docBase,
            LifecycleListener config) {
 
        silence(host, contextPath);
 
        //獲得一個(gè)context容器(StandardContext)
        Context ctx = createContext(host, contextPath);
        ctx.setPath(contextPath);
        ctx.setDocBase(docBase);
 
        if (addDefaultWebXmlToWebapp) {
            ctx.addLifecycleListener(getDefaultWebXmlListener());
        }
 
        ctx.setConfigFile(getWebappConfigFile(docBase, contextPath));
        //把監(jiān)聽器添加到context中去
        ctx.addLifecycleListener(config);
 
        if (addDefaultWebXmlToWebapp && (config instanceof ContextConfig)) {
            // prevent it from looking ( if it finds one - it'll have dup error )
            ((ContextConfig) config).setDefaultWebXml(noDefaultWebXmlPath());
        }
 
        if (host == null) {
            //getHost會(huì)逐層創(chuàng)建容器,并維護(hù)容器父子關(guān)系
            getHost().addChild(ctx);
        } else {
            host.addChild(ctx);
        }
 
        return ctx;
    }

3)維護(hù)各層容器

getHost()方法中得到各層容器,并且維護(hù)父親容器關(guān)系,其中包括,server容器、Engine容器。并且將StandardContext容器通過getHost().addChild(ctx); 調(diào)用containerBase中的addChild()方法維護(hù)在 children 這個(gè)map中。

  public Host getHost() {
        //將每一層的容器都new 出來
        Engine engine = getEngine();
        if (engine.findChildren().length > 0) {
            return (Host) engine.findChildren()[0];
        }
 
        Host host = new StandardHost();
        host.setName(hostname);
        //維護(hù)tomcat中的父子容器
        getEngine().addChild(host);
        return host;
    }

getEngine().addChild(host); 方法選擇調(diào)用父類containerBase中的addChild方法

  @Override
    public void addChild(Container child) {
        if (Globals.IS_SECURITY_ENABLED) {
            PrivilegedAction<Void> dp =
                new PrivilegedAddChild(child);
            AccessController.doPrivileged(dp);
        } else {
            //這里的child 參數(shù)是 context 容器
            addChildInternal(child);
        }
    }

addChildInternal()方法的 核心代碼

 private void addChildInternal(Container child) {
 
        if( log.isDebugEnabled() )
            log.debug("Add child " + child + " " + this);
        synchronized(children) {
            if (children.get(child.getName()) != null)
                throw new IllegalArgumentException("addChild:  Child name '" +
                                                   child.getName() +
                                                   "' is not unique");
            child.setParent(this);  // May throw IAE
            children.put(child.getName(), child);
    }

四、啟動(dòng)容器(tomcat.start())

4.1、方法調(diào)用流程圖

4.2、源碼分析

說明:StandardServer 、StandardService、StandardEngine等容器都是繼承LifecycleBase

所以這里是模板模式的經(jīng)典應(yīng)用

1)逐層啟動(dòng)容器

此時(shí)的server對(duì)應(yīng)的是我們前面創(chuàng)建的StandardServer

  public void start() throws LifecycleException {
        //防止server容器沒有創(chuàng)建
        getServer();
        //獲得connector容器,并且將得到的connector容器設(shè)置到service容器中
        getConnector();
        //這里的start的實(shí)現(xiàn)是在 LifecycleBase類中實(shí)現(xiàn)
        //LifecycleBase方法是一個(gè)模板方法,在tomcat啟動(dòng)流程中非常關(guān)鍵
        server.start();
    }

2) 進(jìn)入start方法

進(jìn)入LifecycelBase中的start方法,其中核心方法是startInternal。

從上面我們知道現(xiàn)在我們調(diào)用的是StandardServer容器的startInternal()方法,所以我們這里選擇的是StandardServer

方法路徑:org.apache.catalina.core.StandardServer.startInternal()

protected void startInternal() throws LifecycleException {
 
        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        setState(LifecycleState.STARTING);
 
        globalNamingResources.start();
 
        // Start our defined Services
        synchronized (servicesLock) {
            //啟動(dòng) service容器,一個(gè)tomcat中可以配置多個(gè)service容器,每個(gè)service容器都對(duì)應(yīng)這我們的一個(gè)服務(wù)應(yīng)用
            for (Service service : services) {
                //對(duì)應(yīng) StandardService.startInternal()
                service.start();
            }
        }
    }

從上面代碼中我們可以看出,啟動(dòng)server容器的時(shí)候需要啟動(dòng)子容器 service容器,從這里開始就是容器 逐層向向內(nèi)引爆,所以接下來就是開始依次調(diào)用各層容器的star方法。在這里就不在贅述。

2)ContainerBase中的startInternal()方法 核心代碼,從這開始啟動(dòng)StandardContext容器

 // Start our child containers, if any
        //在addWwbapp的流程中 addChild方法中加入的,所以這里需要找出來
        //這里找出來的就是 context 容器
        Container children[] = findChildren();
        List<Future<Void>> results = new ArrayList<>();
        for (Container child : children) {
            //通過線程池 異步的方式啟動(dòng)線程池 開始啟動(dòng) context容器,進(jìn)入new StartChild
            results.add(startStopExecutor.submit(new StartChild(child)));
        }

new StartChild(child)) 方法開始啟動(dòng)StandardContext容器

    private static class StartChild implements Callable<Void> {
 
        private Container child;
 
        public StartChild(Container child) {
            this.child = child;
        }
 
        @Override
        public Void call() throws LifecycleException {
            //開始啟動(dòng)context,實(shí)際調(diào)用 StandardContext.startInternal()
            child.start();
            return null;
        }
    }

StandardContext.startInternal() 方法中的核心代碼:

   protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        //lifecycleListeners 在addwebapp方法的第一步中,設(shè)置的監(jiān)聽的 contextConfig對(duì)象
        for (LifecycleListener listener : lifecycleListeners) {
            //這里調(diào)用的是 contextConfig的lifecycleEvent()方法
            listener.lifecycleEvent(event);
        }
    }

進(jìn)入到 contextConfig中的lifecycleEvent()方法

public void lifecycleEvent(LifecycleEvent event) {
 
        // Identify the context we are associated with
        try {
            context = (Context) event.getLifecycle();
        } catch (ClassCastException e) {
            log.error(sm.getString("contextConfig.cce", event.getLifecycle()), e);
            return;
        }
 
        // Process the event that has occurred
        if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
            //完成web.xml的內(nèi)容解析
            configureStart();
        } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {
            beforeStart();
        } else if (event.getType().equals(Lifecycle.AFTER_START_EVENT)) {
            // Restore docBase for management tools
            if (originalDocBase != null) {
                context.setDocBase(originalDocBase);
            }
        } else if (event.getType().equals(Lifecycle.CONFIGURE_STOP_EVENT)) {
            configureStop();
        } else if (event.getType().equals(Lifecycle.AFTER_INIT_EVENT)) {
            init();
        } else if (event.getType().equals(Lifecycle.AFTER_DESTROY_EVENT)) {
            destroy();
        }
 
    }

在上面方法中,完成對(duì)web.xml的加載和解析,同時(shí)加載xml中配置的servlet并且封裝成wrapper對(duì)象。

3)、啟動(dòng)servlet容器,StandardContext.startInternal() 中的 loadOnStartup(findChildren())方法

public boolean loadOnStartup(Container children[]) {
 
        // Collect "load on startup" servlets that need to be initialized
        TreeMap<Integer, ArrayList<Wrapper>> map = new TreeMap<>();
        for (Container child : children) {
            //這里的 Wrapper就是 我們前面封裝的 servlet
            Wrapper wrapper = (Wrapper) child;
            int loadOnStartup = wrapper.getLoadOnStartup();
            if (loadOnStartup < 0) {
                continue;
            }
            Integer key = Integer.valueOf(loadOnStartup);
            ArrayList<Wrapper> list = map.get(key);
            if (list == null) {
                list = new ArrayList<>();
                map.put(key, list);
            }
            list.add(wrapper);
        }
 
        // Load the collected "load on startup" servlets
        for (ArrayList<Wrapper> list : map.values()) {
            for (Wrapper wrapper : list) {
                try {
                    //通過 load 方法  最終會(huì)調(diào)用 servlet的init方法
                    wrapper.load();
                } catch (ServletException e) {
                    getLogger().error(sm.getString("standardContext.loadOnStartup.loadException",
                          getName(), wrapper.getName()), StandardWrapper.getRootCause(e));
                    // NOTE: load errors (including a servlet that throws
                    // UnavailableException from the init() method) are NOT
                    // fatal to application startup
                    // unless failCtxIfServletStartFails="true" is specified
                    if(getComputedFailCtxIfServletStartFails()) {
                        return false;
                    }
                }
            }
        }
        return true;
 
    }

通過 load 方法 最終會(huì)調(diào)用 servlet的init方法。

五、總結(jié)

上面內(nèi)容就是整個(gè)tomcat是如何調(diào)用servlet初始化方法的流程,整個(gè)流程小編的理解,如果有錯(cuò)誤,歡迎指正,小編已經(jīng)在源碼中重要部分進(jìn)行了注釋,所以如果有需要的各位讀者,可以下載我的注釋 源碼,注釋源碼地址:

https://github.com/good-jack/tomcat_source/tree/master

到此這篇關(guān)于詳解從源碼分析tomcat如何調(diào)用Servlet的初始化的文章就介紹到這了,更多相關(guān)tomcat調(diào)用Servlet初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:朝陽 雞西 面試通知 隴南 荊門 運(yùn)城 連云港 遵義

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解從源碼分析tomcat如何調(diào)用Servlet的初始化》,本文關(guān)鍵詞  詳解,從,源碼,分析,tomcat,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解從源碼分析tomcat如何調(diào)用Servlet的初始化》相關(guān)的同類信息!
  • 本頁收集關(guān)于詳解從源碼分析tomcat如何調(diào)用Servlet的初始化的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    色播久久人人爽人人爽人人片视av| aa亚洲一区一区三区| 99久久99久久综合| 少妇饥渴放荡91麻豆| 老司机av在线免费看| 欧美性xxxx极品hd欧美| 美女在线一区二区| 国产精品日本| 久久99国产综合精品女同| 国产传媒一区在线| 少妇人妻精品一区二区三区| 国产最新免费视频| 黄色视屏免费在线观看| 国产美女极度色诱视频www| 亚洲国产精品第一区二区| 日本在线视频网| xxxxxhd亚洲人hd| 成人精品国产免费网站| 亚洲综合福利| 91黄色在线观看| 夜夜操免费视频| 最美情侣韩剧在线播放| 日韩亚洲天堂| 91制片厂在线| 日本在线观看一区二区| 女厕盗摄一区二区三区| 中文字幕乱码一区二区| 黄网站app在线观看大全免费视频| 免费国产阿v视频在线观看| 国产精品777777在线播放| 精品推荐蜜桃传媒| 欧美激情一区二区三区四区| 欧美在线|欧美| 欧美专区第二页| 欧美成人精品福利网站| 欧美高清视频在线高清观看mv色露露十八| 蜜桃传媒av| 美女视频第一区二区三区免费观看网站| 色综合中文字幕| 黄色在线播放网站| 国产美女主播视频一区| 美女被c网站| 成人av动漫在线| av亚洲免费| 精品九九九九| 另类小说视频一区二区| 久久99精品久久久久久秒播放器| 一级片免费网站| 欧美精品欧美精品系列| 久久精品国产一区二区电影| 日韩电影在线观看网站| 日韩欧美不卡一区| 亚洲精品欧美在线| 亚洲欧美久久234| 精品黑人一区二区三区| 国产日韩欧美一区二区东京热| 免费一级特黄3大片视频| 亚洲精蜜桃久在线| www.香蕉视频在线观看| 999视频精品| 久久久久久久久久美女| 最新中文字幕av专区| 国产成人欧美在线观看| 亚洲一区二区三区免费视频| 国产一区二区在线视频播放| 精品国产二区三区| 国产精品久久网| 极品裸体白嫩激情啪啪国产精品| 两个人hd高清在线观看| 一本色道69色精品综合久久| 日韩精品在线免费观看| 伊人久久综合| 91在线免费看片| 亚洲国产精品久久网午夜小说| 免费福利视频一区| 国产视频丨精品|在线观看| 久久91精品国产| 僵尸再翻生在线观看免费国语| 分分操这里只有精品| 久久精品免费网站| 超碰在线97av| 欧美日韩美少妇| 久久精品无码一区二区三区毛片| 欧美日韩18| 欧美大胆a级| 国产卡一卡二在线| 黄色免费在线观看| 欧美激情高清视频| 国产高清不卡一区| 在线黄色的网站| 57pao国产精品一区| 久久久精品三级| 成人激情诱惑| 每日在线观看av| 久久综合久久久久88| 日韩成人免费电影| 五月婷婷综合激情| 欧美日韩xxx| av在线播放观看| 欧美中文字幕在线| 国产日韩影视精品| 毛片基地在线观看| 欧美午夜激情在线| 中文字幕一区日韩电影| 欧美激情视频一区二区三区在线播放| 中文字幕在线观看欧美| 69久久夜色精品国产7777| 国产精品无圣光一区二区| 在线免费观看一级片| 久草综合在线观看| 熟女少妇内射日韩亚洲| 久久国产免费观看| 欧美激情啪啪| 亚洲欧美日韩精品综合在线观看| 中国成人亚色综合网站| 国产视频在线观看一区二区| 国产精品精品久久久久久| 欧美精品成人一区二区三区四区| 欧美一级淫片aaaaaaa视频| 欧美不卡在线| 国产精品密蕾丝视频下载| 久久综合九色综合久99| 黄色成人小视频| 日韩av中文字幕一区| 欧美日本二区| 中文在线最新版地址| 欧美特级xxxxbbbb毛片| 日本欧美精品久久久| 中国av在线播放| 欧美性猛交xxxx免费看| 丰满岳妇乱一区二区三区| 精品国产一区二区三区久久久| 日本三级视频网站| 国产视频观看一区| 一区二区电影免费观看| 中日韩美女免费视频网站在线观看| 国产乱色精品成人免费视频| japanese色国产在线看视频| 看女生喷水的网站在线观看| 欧美中文在线| 久久爱91午夜羞羞| 丁香五六月婷婷久久激情| 日本亚洲三级在线| 91国内视频| 久久精品国产免费| xvideos国产在线视频| 国产麻豆永久视频| 欧美成人手机视频| 成年人视频在线免费看| 日韩中文理论片| 肉大捧一出免费观看网站在线播放| 99久久综合国产精品| 国产在线天堂www网在线观看| 亚洲一区二区三区免费在线观看| 写真福利理论片在线播放| 亚洲国产成人私人影院| 1区2区3区精品视频| 黑人性生活视频| 偷拍女澡堂一区二区三区| 欧美日本亚洲韩国国产| 国产精品815.cc红桃| 欧美视频1区| 午夜影院网站| 亚洲成人tv| 午夜精品久久久久久久99黑人| heyzo在线| 99视频免费播放| eeuss影院www影院入口| 51国偷自产一区二区三区的来源| 欧美一区免费视频| 在线国产亚洲欧美| 欧美色就是色| 全球中文成人在线| 日本一区二区免费不卡| 亚洲自拍欧美精品| 日韩午夜一区| 97在线观看视频国产| 粉嫩精品久久99综合一区| 18岁免费网站| 手机在线观看毛片| 久久久影院一区二区三区| 婷婷四房综合激情五月| 免费看黄资源大全高清| 欧美激情欧美| 中文在线资源| 亚洲精品久久7777777| 日本免费网站视频| 亚洲第一福利视频| 国产视频网站在线| 在线亚洲自拍| 91精品久久久久久久久久久久久| 国产精品成人品| 免费一区视频| 中文字幕在线视频第一页| 久草在线资源福利站| 亚洲综合丁香婷婷六月香| 日本一本在线视频| 午夜性色福利影院| 成人免费看吃奶视频网站| 经典三级久久| 久久全球大尺度高清视频| 欧美激情视频一区二区三区在线播放| 实拍女处破www免费看| 欧美一级本道电影免费专区| 在线观看三级网站| 免费观看毛片网站| 午夜影院在线观看视频| 天海翼一区二区| 国产免费叼嘿网站免费| 欧美性猛交xxxxxxxx| 国产99久久精品| 国产综合av| 亚洲精品乱码久久久久久蜜桃麻豆| 成人在线高清免费| 久久精品视频免费看| 亚洲r级在线观看| 成人国产视频在线观看| 亚洲欧美激情插| 国产a级一级片| 国产91在线|亚洲| 欧洲精品中文字幕| 日韩成人手机在线| 国产在线观看一区| 粉嫩绯色av一区二区在线观看| japanese23hdxxxx日韩| 日本少妇aaa| 激情综合久久| 日韩在线观看成人| 久久午夜国产精品| 色一情一乱一乱一区91av| 91精品亚洲一区在线观看| 91极品尤物在线播放国产| 国产成人精品亚洲线观看| 久操视频在线免费观看| 欧美日韩国产精品自在自线| 久久夜色电影| www.蜜桃av.com| 在线视频手机国产| 成人一区二区三区四区| 久久久久成人精品无码中文字幕| 91香蕉视频免费看| 精品国产凹凸成av人网站| 91国模大尺度私拍在线视频| 国产精品毛片一区二区在线看舒淇| 久久久www免费人成黑人精品| 国产精品美女高潮无套| 国产人妻精品久久久久野外| 国产精品草莓在线免费观看| 久久精品欧美| 久久99九九99精品| 亚洲国产精品久久久久秋霞蜜臀| 欧美精品少妇videofree| a级影片在线观看| 成人97在线观看视频| 男人插曲女人视频免费| 亚洲一区二区在线免费| 韩国精品久久久999| 国产xxxx做受性欧美88| √天堂资源地址在线官网| 在线观看 中文字幕| 制服丝袜第一页在线观看| 欧洲精品码一区二区三区免费看| 激情av综合| 大地资源网在线观看免费官网| 女同视频在线观看| 高潮毛片又色又爽免费| 青青草精品毛片| 国产在线观看91| 国产亚洲精品久久久久久青梅| crdy在线观看欧美| 亚洲国产一区二区久久久777| 国内精品亚洲| 中文字幕人妻一区二区三区视频| 日本不卡一区二区在线观看| 91一区在线| c#hpsocket| 成年人免费网站在线观看| 欧美激情在线观看视频免费| 日韩片在线观看| 精品视频久久久久| 精品少妇人妻av一区二区三区| 一区二区三区四区电影| 欧美一区二区三区久久综合| wwwwxxxx在线观看| 国产免费a∨片在线观看不卡| 在线免费观看日韩av| 亚洲日本在线观看视频| 特级毛片www| 久久午夜av| 国产高清一区二区三区四区| 加勒比视频一区| 九色视频网站在线观看| 一个人看的www片免费高清视频| 欧美另类69精品久久久久9999| 日韩午夜激情电影| 久久五月情影视| 久久综合给合久久狠狠色| 九色|91porny| 亚州成人av在线| 老司机久久99久久精品播放免费| 国模精品一区二区三区| 欧美激情自拍偷拍| 456成人影院在线观看| 婷婷免费在线视频| 99久久久久国产精品免费| 亚洲精品一区二区三区四区| 青草视频.com| 中文字幕精品久久| 亚洲精品国产精品国自产观看| 人妻少妇偷人精品久久久任期| 精品72久久久久中文字幕| 亚洲成色最大综合在线| 国产美女搞久久| 国产又爽又黄又嫩又猛又粗| 欧美性猛交 xxxx| 国产视频一区在线观看一区免费| 欧美精品在线网站| 中国国产一级毛片| 中文写幕一区二区三区免费观成熟| 午夜视频在线观看一区二区| 国产成人永久免费视频| 精品综合免费视频观看| 天使萌一区二区三区免费观看| 69精品久久久| 黄色av成人| 久久久久99精品成人片试看| 丁香婷婷深情五月亚洲| 日产精品久久久|