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

SpringBoot的兩種啟動(dòng)方式原理,你學(xué)會(huì)了嗎?

開(kāi)發(fā) 前端
關(guān)于Tomcat的屬性都在?org.springframework.boot.autoconfigure.web.ServerProperties?配置類中做了定義,我們只需在application.properties配置屬性做配置即可。通用的Servlet容器配置都以?server?作為前綴。

使用內(nèi)置tomcat啟動(dòng)

配置案例

啟動(dòng)方式

  1. IDEA中main函數(shù)啟動(dòng)
  2. mvn springboot-run
  3. java -jar XXX.jar 使用這種方式時(shí),為保證服務(wù)在后臺(tái)運(yùn)行,會(huì)使用nohup
nohup java -jar -Xms128m -Xmx128m -Xss256k -XX:+PrintGCDetails -XX:+PrintHeapAtGC -Xloggc:/data/log/web-gc.log web.jar >/data/log/web.log &

使用java -jar默認(rèn)情況下,不會(huì)啟動(dòng)任何嵌入式Application Server,該命令只是啟動(dòng)一個(gè)執(zhí)行jar main的JVM進(jìn)程,當(dāng)spring-boot-starter-web包含嵌入式tomcat服務(wù)器依賴項(xiàng)時(shí),執(zhí)行java -jar則會(huì)啟動(dòng)Application Server

配置內(nèi)置tomcat屬性

關(guān)于Tomcat的屬性都在 org.springframework.boot.autoconfigure.web.ServerProperties 配置類中做了定義,我們只需在application.properties配置屬性做配置即可。通用的Servlet容器配置都以 server 作為前綴

#配置程序端口,默認(rèn)為8080
server.port= 8080
#用戶會(huì)話session過(guò)期時(shí)間,以秒為單位
server.session.timeout=
#配置默認(rèn)訪問(wèn)路徑,默認(rèn)為/
server.context-path=

而Tomcat特有配置都以 server.tomcat 作為前綴

# 配置Tomcat編碼,默認(rèn)為UTF-8
server.tomcat.uri-encoding=UTF-8
# 配置最大線程數(shù)
server.tomcat.max-threads=1000

注意:使用內(nèi)置tomcat不需要有tomcat-embed-jasper和spring-boot-starter-tomcat依賴,因?yàn)樵趕pring-boot-starter-web依賴中已經(jīng)集成了tomcat

原理

從main函數(shù)說(shuō)起

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class[]{primarySource}, args);
}
 
// 這里run方法返回的是ConfigurableApplicationContext
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
  return (new SpringApplication(primarySources)).run(args);
}
public ConfigurableApplicationContext run(String... args) {
 ConfigurableApplicationContext context = null;
 Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
 SpringApplicationRunListeners listeners = this.getRunListeners(args);
 listeners.starting();

 Collection exceptionReporters;
try {
  ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
  ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);

//打印banner,這里可以自己涂鴉一下,換成自己項(xiàng)目的logo
  Banner printedBanner = this.printBanner(environment);

//創(chuàng)建應(yīng)用上下文
  context = this.createApplicationContext();
  exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);

//預(yù)處理上下文
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

//刷新上下文
this.refreshContext(context);

//再刷新上下文
this.afterRefresh(context, applicationArguments);

  listeners.started(context);
this.callRunners(context, applicationArguments);
 } catch (Throwable var10) {

 }

try {
  listeners.running(context);
return context;
 } catch (Throwable var9) {

 }
}

既然我們想知道tomcat在SpringBoot中是怎么啟動(dòng)的,那么run方法中,重點(diǎn)關(guān)注創(chuàng)建應(yīng)用上下文(createApplicationContext)和刷新上下文(refreshContext)。

創(chuàng)建上下文

//創(chuàng)建上下文
protected ConfigurableApplicationContext createApplicationContext() {
 Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
   switch(this.webApplicationType) {
    case SERVLET:
                    //創(chuàng)建AnnotationConfigServletWebServerApplicationContext
        contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
     break;
    case REACTIVE:
     contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
     break;
    default:
     contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
   }
  } catch (ClassNotFoundException var3) {
   thrownew IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
  }
 }

return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
}

這里會(huì)創(chuàng)建AnnotationConfigServletWebServerApplicationContext類。而AnnotationConfigServletWebServerApplicationContext類繼承了ServletWebServerApplicationContext,而這個(gè)類是最終集成了AbstractApplicationContext。

刷新上下文

//SpringApplication.java
//刷新上下文
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
   context.registerShutdownHook();
  } catch (AccessControlException var3) {
  }
 }
}

//這里直接調(diào)用最終父類AbstractApplicationContext.refresh()方法
protected void refresh(ApplicationContext applicationContext) {
 ((AbstractApplicationContext)applicationContext).refresh();
}
//AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
  ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);

try {
   this.postProcessBeanFactory(beanFactory);
   this.invokeBeanFactoryPostProcessors(beanFactory);
   this.registerBeanPostProcessors(beanFactory);
   this.initMessageSource();
   this.initApplicationEventMulticaster();
   //調(diào)用各個(gè)子類的onRefresh()方法,也就說(shuō)這里要回到子類:ServletWebServerApplicationContext,調(diào)用該類的onRefresh()方法
   this.onRefresh();
   this.registerListeners();
   this.finishBeanFactoryInitialization(beanFactory);
   this.finishRefresh();
  } catch (BeansException var9) {
   this.destroyBeans();
   this.cancelRefresh(var9);
   throw var9;
  } finally {
   this.resetCommonCaches();
  }

 }
}
//ServletWebServerApplicationContext.java
//在這個(gè)方法里看到了熟悉的面孔,this.createWebServer,神秘的面紗就要揭開(kāi)了。
protected void onRefresh() {
super.onRefresh();
try {
this.createWebServer();
 } catch (Throwable var2) {

 }
}

//ServletWebServerApplicationContext.java
//這里是創(chuàng)建webServer,但是還沒(méi)有啟動(dòng)tomcat,這里是通過(guò)ServletWebServerFactory創(chuàng)建,那么接著看下ServletWebServerFactory
private void createWebServer() {
 WebServer webServer = this.webServer;
 ServletContext servletContext = this.getServletContext();
if (webServer == null && servletContext == null) {
  ServletWebServerFactory factory = this.getWebServerFactory();
this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
 } elseif (servletContext != null) {
try {
   this.getSelfInitializer().onStartup(servletContext);
  } catch (ServletException var4) {

  }
 }

this.initPropertySources();
}

//接口
publicinterface ServletWebServerFactory {
    WebServer getWebServer(ServletContextInitializer... initializers);
}

//實(shí)現(xiàn)
AbstractServletWebServerFactory
JettyServletWebServerFactory
TomcatServletWebServerFactory
UndertowServletWebServerFactory

這里ServletWebServerFactory接口有4個(gè)實(shí)現(xiàn)類,對(duì)應(yīng)著四種容器:

而其中我們常用的有兩個(gè):TomcatServletWebServerFactory和JettyServletWebServerFactory。

//TomcatServletWebServerFactory.java
//這里我們使用的tomcat,所以我們查看TomcatServletWebServerFactory。到這里總算是看到了tomcat的蹤跡。
@Override
public WebServer getWebServer(ServletContextInitializer... initializers) {
 Tomcat tomcat = new Tomcat();
 File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
 tomcat.setBaseDir(baseDir.getAbsolutePath());
    //創(chuàng)建Connector對(duì)象
 Connector connector = new Connector(this.protocol);
 tomcat.getService().addConnector(connector);
 customizeConnector(connector);
 tomcat.setConnector(connector);
 tomcat.getHost().setAutoDeploy(false);
 configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
  tomcat.getService().addConnector(additionalConnector);
 }
 prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}

protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
returnnew TomcatWebServer(tomcat, getPort() >= 0);
}

//Tomcat.java
//返回Engine容器,看到這里,如果熟悉tomcat源碼的話,對(duì)engine不會(huì)感到陌生。
public Engine getEngine() {
    Service service = getServer().findServices()[0];
    if (service.getContainer() != null) {
        return service.getContainer();
    }
    Engine engine = new StandardEngine();
    engine.setName( "Tomcat" );
    engine.setDefaultHost(hostname);
    engine.setRealm(createDefaultRealm());
    service.setContainer(engine);
    return engine;
}
//Engine是最高級(jí)別容器,Host是Engine的子容器,Context是Host的子容器,Wrapper是Context的子容器

getWebServer這個(gè)方法創(chuàng)建了Tomcat對(duì)象,并且做了兩件重要的事情:把Connector對(duì)象添加到tomcat中,configureEngine(tomcat.getEngine());

getWebServer方法返回的是TomcatWebServer。

//TomcatWebServer.java
//這里調(diào)用構(gòu)造函數(shù)實(shí)例化TomcatWebServer
public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
 Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
 initialize();
}

private void initialize() throws WebServerException {
    //在控制臺(tái)會(huì)看到這句日志
 logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
synchronized (this.monitor) {
try {
   addInstanceIdToEngineName();

   Context context = findContext();
   context.addLifecycleListener((event) -> {
    if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
     removeServiceConnectors();
    }
   });

   //===啟動(dòng)tomcat服務(wù)===
   this.tomcat.start();

   rethrowDeferredStartupExceptions();

   try {
    ContextBindings.bindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
   }
   catch (NamingException ex) {
                
   }
            
            //開(kāi)啟阻塞非守護(hù)進(jìn)程
   startDaemonAwaitThread();
  }
catch (Exception ex) {
   stopSilently();
   destroySilently();
   thrownew WebServerException("Unable to start embedded Tomcat", ex);
  }
 }
}
//Tomcat.java
public void start() throws LifecycleException {
 getServer();
 server.start();
}
//這里server.start又會(huì)回到TomcatWebServer的
public void stop() throws LifecycleException {
 getServer();
 server.stop();
}
//TomcatWebServer.java
//啟動(dòng)tomcat服務(wù)
@Override
public void start() throws WebServerException {
synchronized (this.monitor) {
if (this.started) {
   return;
  }
try {
   addPreviouslyRemovedConnectors();
   Connector connector = this.tomcat.getConnector();
   if (connector != null && this.autoStart) {
    performDeferredLoadOnStartup();
   }
   checkThatConnectorsHaveStarted();
   this.started = true;
   //在控制臺(tái)打印這句日志,如果在yml設(shè)置了上下文,這里會(huì)打印
   logger.info("Tomcat started on port(s): " + getPortsDescription(true) + " with context path '"
     + getContextPath() + "'");
  }
catch (ConnectorStartFailedException ex) {
   stopSilently();
   throw ex;
  }
catch (Exception ex) {
   thrownew WebServerException("Unable to start embedded Tomcat server", ex);
  }
finally {
   Context context = findContext();
   ContextBindings.unbindClassLoader(context, context.getNamingToken(), getClass().getClassLoader());
  }
 }
}

//關(guān)閉tomcat服務(wù)
@Override
public void stop() throws WebServerException {
synchronized (this.monitor) {
boolean wasStarted = this.started;
try {
   this.started = false;
   try {
    stopTomcat();
    this.tomcat.destroy();
   }
   catch (LifecycleException ex) {
    
   }
  }
catch (Exception ex) {
   thrownew WebServerException("Unable to stop embedded Tomcat", ex);
  }
finally {
   if (wasStarted) {
    containerCounter.decrementAndGet();
   }
  }
 }
}

使用外置tomcat部署

配置案例

外置Tomcat啟動(dòng)SpringBoot源碼點(diǎn)擊這里

繼承SpringBootServletInitializer

  • 外部容器部署的話,就不能依賴于Application的main函數(shù)了,而是要以類似于web.xml文件配置的方式來(lái)啟動(dòng)Spring應(yīng)用上下文,此時(shí)需要在啟動(dòng)類中繼承SpringBootServletInitializer,并重寫configure方法;還添加 @SpringBootApplication 注解,這是為了能掃描到所有Spring注解的bean

方式一:?jiǎn)?dòng)類繼承SpringBootServletInitializer實(shí)現(xiàn)configure:

@SpringBootApplication
public class SpringBootHelloWorldTomcatApplication extends SpringBootServletInitializer {
 @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }
}

這個(gè)類的作用與在web.xml中配置負(fù)責(zé)初始化Spring應(yīng)用上下文的監(jiān)聽(tīng)器作用類似,只不過(guò)在這里不需要編寫額外的XML文件了。

方式二:新增加一個(gè)類繼承SpringBootServletInitializer實(shí)現(xiàn)configure:

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        //此處的Application.class為帶有@SpringBootApplication注解的啟動(dòng)類
        return builder.sources(Application.class);
    }
}

pom.xml修改tomcat相關(guān)的配置

首先需要將 jar 變成war <packaging>war</packaging>

如果要將最終的打包形式改為war的話,還需要對(duì)pom.xml文件進(jìn)行修改,因?yàn)閟pring-boot-starter-web中包含內(nèi)嵌的tomcat容器,所以直接部署在外部容器會(huì)沖突報(bào)錯(cuò)。因此需要將內(nèi)置tomcat排除

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

在這里需要移除對(duì)嵌入式Tomcat的依賴,這樣打出的war包中,在lib目錄下才不會(huì)包含Tomcat相關(guān)的jar包,否則將會(huì)出現(xiàn)啟動(dòng)錯(cuò)誤。

但是移除了tomcat后,原始的sevlet也被移除了,因此還需要額外引入servet的包

<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
</dependency>

注意的問(wèn)題

此時(shí)打成的包的名稱應(yīng)該和 application.properties 的 server.context-path=/test 保持一致

<build>
    <finalName>test</finalName>
</build>

如果不一樣發(fā)布到tomcat的webapps下上下文會(huì)變化

原理

tomcat不會(huì)主動(dòng)去啟動(dòng)springboot應(yīng)用 ,, 所以tomcat啟動(dòng)的時(shí)候肯定調(diào)用了SpringBootServletInitializer的SpringApplicationBuilder , 就會(huì)啟動(dòng)springboot。

ServletContainerInitializer的實(shí)現(xiàn)放在jar包的META-INF/services文件夾下,有一個(gè)名為javax.servlet.ServletContainerInitializer的文件,內(nèi)容就是ServletContainerInitializer的實(shí)現(xiàn)類的全類名。當(dāng)servlet容器啟動(dòng)時(shí)候就會(huì)去該文件中找到ServletContainerInitializer的實(shí)現(xiàn)類,從而創(chuàng)建它的實(shí)例調(diào)用onstartUp。這里就是用了SPI機(jī)制

HandlesTypes(WebApplicationInitializer.class)

  • @HandlesTypes傳入的類為ServletContainerInitializer感興趣的
  • 容器會(huì)自動(dòng)在classpath中找到 WebApplicationInitializer,會(huì)傳入到onStartup方法的webAppInitializerClasses中
  • Set<Class<?>> webAppInitializerClasses這里面也包括之前定義的TomcatStartSpringBoot
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
      throws ServletException {

   List<WebApplicationInitializer> initializers = new LinkedList<>();

   if (webAppInitializerClasses != null) {
      for (Class<?> waiClass : webAppInitializerClasses) {
        // 如果不是接口 不是抽象 跟WebApplicationInitializer有關(guān)系  就會(huì)實(shí)例化
         if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
               WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
            try {
               initializers.add((WebApplicationInitializer)
                     ReflectionUtils.accessibleConstructor(waiClass).newInstance());
            }
            catch (Throwable ex) {
               thrownew ServletException("Failed to instantiate WebApplicationInitializer class", ex);
            }
         }
      }
   }

   if (initializers.isEmpty()) {
      servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
      return;
   }

   servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
   // 排序
   AnnotationAwareOrderComparator.sort(initializers);
   for (WebApplicationInitializer initializer : initializers) {
      initializer.onStartup(servletContext);
   }
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
   // Logger initialization is deferred in case an ordered
   // LogServletContextInitializer is being used
   this.logger = LogFactory.getLog(getClass());
   WebApplicationContext rootApplicationContext = createRootApplicationContext(servletContext);
   if (rootApplicationContext != null) {
      servletContext.addListener(new SpringBootContextLoaderListener(rootApplicationContext, servletContext));
   }
   else {
      this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not "
            + "return an application context");
   }
}

SpringBootServletInitializer

protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
   SpringApplicationBuilder builder = createSpringApplicationBuilder();
   builder.main(getClass());
   ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
   if (parent != null) {
      this.logger.info("Root context already created (using as parent).");
      servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
      builder.initializers(new ParentContextApplicationContextInitializer(parent));
   }
   builder.initializers(new ServletContextApplicationContextInitializer(servletContext));
   builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);
   // 調(diào)用configure
   builder = configure(builder); //①
   builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
   SpringApplication application = builder.build();//②
   if (application.getAllSources().isEmpty()
         && MergedAnnotations.from(getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
      application.addPrimarySources(Collections.singleton(getClass()));
   }
   Assert.state(!application.getAllSources().isEmpty(),
         "No SpringApplication sources have been defined. Either override the "
               + "configure method or add an @Configuration annotation");
   // Ensure error pages are registered
   if (this.registerErrorPageFilter) {
      application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
   }
   application.setRegisterShutdownHook(false);
   return run(application);//③
}

① 當(dāng)調(diào)用configure就會(huì)來(lái)到TomcatStartSpringBoot .configure,將Springboot啟動(dòng)類傳入到builder.source

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(Application.class);
}

② 調(diào)用SpringApplication application = builder.build(); 就會(huì)根據(jù)傳入的Springboot啟動(dòng)類來(lái)構(gòu)建一個(gè)SpringApplication

public SpringApplication build(String... args) {
   configureAsChildIfNecessary(args);
   this.application.addPrimarySources(this.sources);
   return this.application;
}

③ 調(diào)用 return run(application); 就會(huì)啟動(dòng)springboot應(yīng)用

protected WebApplicationContext run(SpringApplication application) {
   return (WebApplicationContext) application.run();
}

也就相當(dāng)于Main函數(shù)啟動(dòng):

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

之后的流程就與上面 使用內(nèi)置Tomcat的Main函數(shù)一致了

責(zé)任編輯:武曉燕 來(lái)源: Seven97
相關(guān)推薦

2023-05-05 06:54:07

MySQL數(shù)據(jù)查詢

2023-10-06 14:49:21

SentinelHystrixtimeout

2024-05-29 07:47:30

SpringJava@Resource

2023-10-30 11:40:36

OOM線程池單線程

2023-03-30 08:26:31

DNSTCPUDP

2023-03-31 08:16:39

CDN網(wǎng)絡(luò)數(shù)據(jù)

2023-11-29 07:23:04

參數(shù)springboto

2024-03-12 08:37:32

asyncawaitJavaScript

2021-10-26 17:26:46

JVM架構(gòu)模型

2025-09-03 04:11:00

2023-11-27 07:26:42

Springboot容器

2023-08-08 08:23:08

Spring日志?線程池

2022-07-08 09:27:48

CSSIFC模型

2024-01-19 08:25:38

死鎖Java通信

2023-07-26 13:11:21

ChatGPT平臺(tái)工具

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-01-10 08:43:15

定義DDD架構(gòu)

2024-02-02 11:03:11

React數(shù)據(jù)Ref

2023-08-01 12:51:18

WebGPT機(jī)器學(xué)習(xí)模型

2024-01-02 12:05:26

Java并發(fā)編程
點(diǎn)贊
收藏

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

中文字幕亚洲自拍| 亚洲一级电影视频| 91精品国产自产在线老师啪| av黄色免费在线观看| 日本少妇精品亚洲第一区| 亚洲在线免费播放| 欧美极品视频一区二区三区| 伊人久久成人网| 欧美激情麻豆| 亚洲欧美日韩精品久久| 国产精品久久久久久9999| 96av在线| 国产精品久久久久久久久免费丝袜| 亚洲最大av网| av片免费观看| 欧美日韩综合| 亚洲性夜色噜噜噜7777| 女教师高潮黄又色视频| 澳门成人av网| 一区二区三区欧美日韩| 日韩aⅴ视频一区二区三区| 97在线播放免费观看| 亚洲精品护士| 久久久精品一区| 黄色在线观看av| 伊人亚洲精品| 在线观看视频一区| 国产一二三区在线播放| 秋霞影院午夜丰满少妇在线视频| 99在线热播精品免费| 91色在线观看| 中文天堂在线视频| 国产精品色网| 韩国三级电影久久久久久| 国产第一页浮力| 一二三四视频在线中文| 黄色片网站在线播放| 久久免费国产精品1| 国产一区二区三区国产| 中文字幕一区二区三区四区不卡| 高清视频一区| 99久久精品国产一区色| 日产国产高清一区二区三区| 2020国产精品视频| 国产一级在线免费观看| 综合av在线| 久久精品这里热有精品| jizzjizzjizz国产| 精品一区电影| 伊人亚洲福利一区二区三区| 在线免费观看a级片| 国产亚洲成av人片在线观黄桃| 欧美精品日韩精品| 久久99爱视频| 欧美激情福利| 久久人人97超碰com| 亚洲欧洲在线免费| 亚洲黄色在线网站| 欧美亚洲tv| 日韩电影大全免费观看2023年上 | av最新在线| 亚洲一级二级三级| 日韩美女爱爱视频| 女人天堂av在线播放| 樱桃视频在线观看一区| 欧美性猛交内射兽交老熟妇| 羞羞视频在线免费国产| 亚洲亚洲精品在线观看| 国产夫妻自拍一区| 国产福利片在线观看| 欧美日韩精品在线| 国产黄色特级片| 日本黄色一区| 欧美一区三区四区| 亚洲少妇中文字幕| 人妖一区二区三区| 国产亚洲成精品久久| 东京热无码av男人的天堂| 色婷婷一区二区三区| 米奇精品一区二区三区在线观看| 久草免费新视频| 日韩午夜在线| 国产97在线视频| 亚洲无码久久久久| 国产成人精品综合在线观看| 精品国产电影| 久cao在线| 精品久久久久久久中文字幕 | 国产成人综合自拍| 麻豆精品视频| 黄色网址在线免费| 亚洲国产精品久久不卡毛片 | 国产精品99久久久久久宅男| 国产日韩欧美二区| av在线播放av| 亚洲国产成人va在线观看天堂| 黄色片视频在线播放| 精品国模一区二区三区欧美| 日韩国产一区三区| 欧美性x x x| 亚洲综合社区| 91久久久久久久一区二区| 四季av日韩精品一区| 中文字幕不卡在线播放| 蜜臀精品一区二区| 激情中国色综合| 日韩精品电影网| 久久久精品少妇| 欧美亚洲在线| 国产欧美日韩视频一区二区三区| 成年人在线观看视频| 亚洲精品视频在线| 国产素人在线观看| 激情五月综合婷婷| 亚洲美女中文字幕| 爱爱视频免费在线观看| 国产视频一区欧美| 成人一区二区电影| 黄色av免费在线看| 国产精品欧美综合在线| 国产69精品久久久久久久| 视频精品导航| 亚洲娇小xxxx欧美娇小| 亚洲二区在线播放| 久久国产欧美| 亚洲影视九九影院在线观看| se在线电影| 亚洲mv在线观看| 国产精品嫩草影院8vv8| 西野翔中文久久精品国产| 欧美成人合集magnet| 日本熟女毛茸茸| 精品一区二区日韩| 亚洲高清资源综合久久精品| 大香伊人久久| 91精品中文字幕一区二区三区| 少妇大叫太粗太大爽一区二区| 欧美在线91| 国产精品九九九| 免费观看成年在线视频网站| 亚洲福利视频导航| 999热精品视频| 久久一区二区三区喷水| 日本中文字幕不卡免费| 丰满人妻一区二区| 欧美国产日韩a欧美在线观看| 亚洲国产精品久久久久爰色欲| 亚洲国产欧美在线观看| 久久久999精品| 国产精品露脸视频| 久久久av毛片精品| 日韩欧美精品在线观看视频| 免费久久久久久久久| 午夜精品美女自拍福到在线| www.日日夜夜| 亚洲欧美成aⅴ人在线观看| 韩国中文字幕av| 国语产色综合| 日本亚洲欧洲色| 国产精品麻豆一区二区三区 | 国产在线播放一区三区四| 五月天丁香综合久久国产| 网友自拍亚洲| 日韩精品中文字幕有码专区| 亚洲精品国产无码| 久久精品亚洲精品国产欧美| 国产二区视频在线播放| 加勒比色老久久爱综合网| 美女精品久久久| 精品美女www爽爽爽视频| 性欧美疯狂xxxxbbbb| 伦理片一区二区| 亚洲精品极品| 免费日韩电影在线观看| 欧美成人h版| 一区二区三区四区视频| 国产欧美久久久| 一区二区在线观看免费| 韩国三级在线看| 99视频一区| 欧美激情第六页| 欧美成人高清视频在线观看| 一区二区av在线| 性一交一乱一色一视频麻豆| 亚洲国产日日夜夜| 风间由美一二三区av片| 日韩黄色片在线观看| 一本一生久久a久久精品综合蜜| 久久av影院| 国语自产精品视频在免费| 天堂在线视频观看| 欧美亚洲一区二区在线| 亚洲欧美精品aaaaaa片| 岛国av在线一区| 日韩免费高清在线| 黄色一区二区三区四区| 欧美污视频久久久| 婷婷成人av| 91精品国产91久久久久久| 国产精品一区二区三区四区色| 欧美午夜精品免费| 亚洲一区 视频| 国产日韩欧美精品电影三级在线| 亚洲欧美日韩一二三区| 国产情侣久久| 亚洲图片小说在线| 99久久免费精品国产72精品九九| 欧美性受xxxx白人性爽| 国产在线二区| 日韩精品999| 国产av无码专区亚洲a∨毛片| 午夜成人在线视频| 99热6这里只有精品| 91在线观看免费视频| 蜜桃福利午夜精品一区| 亚洲深爱激情| 4444在线观看| 欧美色图国产精品| 久久久久免费网| 久久伊人影院| 国产精品久久久久久亚洲调教| 日本一本在线免费福利| 伊人久久久久久久久久| 欧美男男同志| 欧美成人精精品一区二区频| 中国女人真人一级毛片| 欧美视频精品一区| 成人观看免费视频| 久久在线观看免费| 精品无码国产一区二区三区51安| 极品美女销魂一区二区三区| 国产亚洲综合视频| 狠狠干综合网| 99亚洲国产精品| 色呦哟—国产精品| 亚洲激情一区二区| 精品国产乱码久久久久久蜜坠欲下 | 男男视频亚洲欧美| 国产精品自拍片| 天天色综合色| 一区二区精品免费视频| blacked蜜桃精品一区| 精品一区久久| 韩国女主播一区二区三区| 国产精品久久久久久久久久直播| 亚洲国产天堂| 国产日韩精品在线| 成人国产激情| 国产成一区二区| 成人免费观看在线观看| 69视频在线免费观看| 欧美xxx黑人xxx水蜜桃| 九九久久久久99精品| 好操啊在线观看免费视频| 久久久精品美女| 日本a在线播放| 最近2019年手机中文字幕| 成人18在线| 中文字幕亚洲欧美日韩2019| 激情视频在线观看| 久久久av免费| 特级毛片在线| 久久久久久久久久久亚洲| 黄色网页在线看| 久久久久女教师免费一区| 久久www人成免费看片中文| 欧美高清一级大片| 成年人视频免费在线播放| 日韩中文字幕网址| 日皮视频在线观看| 久久久久久尹人网香蕉| free性m.freesex欧美| 2019中文字幕在线免费观看| 亚洲最大网站| 成人免费福利视频| 一本一道久久a久久| 国产在线精品一区二区中文| 欧美精品中文| 欧美精品人人做人人爱视频| 久久最新网址| 亚洲一卡二卡三卡四卡无卡网站在线看| 色综合天天综合网中文字幕| 天堂v在线视频| 欧美91精品| 色欲色香天天天综合网www| 一区二区精品| 我要看一级黄色大片| 狠狠久久亚洲欧美| 国产偷人妻精品一区| 日本一区二区综合亚洲| 日日噜噜夜夜狠狠久久波多野| 亚洲综合免费观看高清完整版在线| 在线观看国产亚洲| 欧美午夜精品理论片a级按摩| 国产情侣av在线| 亚洲福利在线观看| 都市激情在线视频| 欧美丰满少妇xxxxx做受| 欧美激情网站| 国产在线精品成人一区二区三区| 9国产精品午夜| 国产精品一区二区a| 四虎8848精品成人免费网站| 韩国无码av片在线观看网站| 国产精品试看| 欧美一级免费在线| 99国产精品久久久久久久久久久| 在线看的片片片免费| 午夜精品久久久久久久久久| 最新中文字幕在线观看视频| 日韩欧美一区二区免费| 中文字幕在线免费| 韩国视频理论视频久久| 国产激情欧美| 久久亚洲精品欧美| 首页国产精品| 国产视频一区二区视频| 国产成人av在线影院| 无码人妻丰满熟妇啪啪欧美| 亚洲成人动漫一区| av网站免费播放| 亚洲免费av片| 97超碰免费在线| 91免费欧美精品| 日韩大片在线播放| 成人中文字幕在线播放| 韩国午夜理伦三级不卡影院| 欧美高清性xxxx| 亚洲综合在线五月| 99久久婷婷国产一区二区三区| 亚洲三级黄色在线观看| 91超碰国产在线| 91超碰在线电影| 911精品美国片911久久久| 欧美精品成人网| 不卡av在线网| 欧美特级一级片| 欧洲精品一区二区| 高h视频在线| 欧美在线一区二区三区四| 视频一区国产| 国产911在线观看| 国产成人亚洲综合a∨婷婷| 亚洲av无一区二区三区| 在线观看视频欧美| 九色蝌蚪在线| 国产精品久久久999| 九九免费精品视频在线观看| 国精产品一区一区三区视频| 国产成人综合亚洲91猫咪| 日本在线一级片| 91精品在线免费| av网站免费在线观看| 国产日韩中文字幕| 久久人人99| 日韩av一卡二卡三卡| 国产精品久久久久影视| 成人一级免费视频| 在线电影中文日韩| 91超碰碰碰碰久久久久久综合| 青青草原成人| 亚洲欧美激情诱惑| 少妇av片在线观看| 欧美日韩国产欧美日美国产精品| 成年人在线视频免费观看| 日韩女在线观看| 成人免费a**址| 久久精品免费网站| 欧美激情一区二区在线| 天天想你在线观看完整版电影免费| 国产成人免费看一级大黄| 国产一区二区三区在线视频| 欧美日韩免费观看视频| 日本高清一区| 九九热在线视频观看这里只有精品| 四虎影视一区二区| 欧美精品在线视频| 在线视频1区2区| 国产91视觉| 国产亚洲精品自拍| 国产精久久一区二区三区| 欧美性猛片aaaaaaa做受| 成年人网站在线| 欧美一级黄色片| 婷婷开心激情网| 欧美做爰性生交视频| 日韩a一区二区| 国产老头和老头xxxx×| 亚洲一区二区三区四区不卡| 五十路在线视频| 国产欧美精品一区二区三区介绍| 欧美高清一区| brazzers精品成人一区| 欧美日本在线播放| 密臀av在线| 欧美一区二区三区电影在线观看| 男女男精品视频| 久久国产视频播放| 伊人久久久久久久久久| 婷婷视频一区二区三区|