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

Springboot注冊(cè)Servlet幾種方式你都知道??jī)?nèi)部實(shí)現(xiàn)原理解析

開(kāi)發(fā) 前端
本篇介紹在Springboot環(huán)境下Servlet如何被注冊(cè)到Servlet容器中。這動(dòng)態(tài)注冊(cè)Servlet的相關(guān)API都是在Servlet3.0規(guī)范中才有的。

[[410292]]

環(huán)境:springboot2.3.9.RELEASE

1 Servlet注冊(cè)

方式1:

在配置類(lèi)(啟動(dòng)類(lèi))上添加@ServletComponentScan注解

  1. @SpringBootApplication 
  2. @ServletComponentScan 
  3. public class SpringBootComprehensiveApplication 

Servlet類(lèi)上添加@WebServlet注解接口

  1. @WebServlet("/hello"
  2. public class MyServlet extends HttpServlet { 
  3. }     

對(duì)應(yīng)的Filter, Linstener有:@WebFilter, @WebListener

方式2:

通過(guò)向IOC容器添加ServletRegistrationBean方式;該種方式可以在Servlet中注入其它Bean或者讀取application.properties配置信息等。對(duì)應(yīng)的filter, Listener有對(duì)應(yīng)的bean;FilterRegistrationBean,ServletListenerRegistrationBean

  1. @Bean 
  2. public ServletRegistrationBean<MyServlet> servlet() { 
  3.   ServletRegistrationBean<MyServlet> servlet = new ServletRegistrationBean<>(new MyServlet()) ; 
  4.   servlet.addUrlMappings("/hello") ;  
  5.   return servlet ; 

 方式3:

動(dòng)態(tài)注冊(cè)Servlet

  1. @Component 
  2. public class DynamicRegServlet implements ServletContextInitializer { 
  3.  
  4.   @Override 
  5.   public void onStartup(ServletContext servletContext) throws ServletException { 
  6.     ServletRegistration initServlet = servletContext.addServlet("myServlet", MyServlet.class) ; 
  7.     initServlet.addMapping("/hello") ; 
  8.   } 
  9.  

 該種方式是利用的Servlet3.0開(kāi)始才有的功能,通過(guò)SPI技術(shù)在容器啟動(dòng)的時(shí)候做一些初始化工作,比如注冊(cè)Servlet等。在Servle規(guī)范中通過(guò)

ServletContainerInitializer實(shí)現(xiàn)該功能。

該Servlet規(guī)范的開(kāi)發(fā)流程如下;

2、配置

ServletContainerInitializer

在src/META-INF/services下新建

javax.servlet.ServletContainerInitializer文件,文件內(nèi)容為ServletContainerInitializer接口的實(shí)現(xiàn)類(lèi)(完整的包名+類(lèi)名)如下:

  1. com.pack.container.config.CustomServletInitializer 

CustomServletInitializer類(lèi)

  1. @HandlesTypes({ScoreWebInit.class}) 
  2. public class CustomServletInitializer implements ServletContainerInitializer { 
  3.   @Override 
  4.   public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException { 
  5.     c.forEach(web -> { 
  6.       try { 
  7.         ((ScoreWebInit)web.newInstance()).pay() ; 
  8.       } catch (InstantiationException e) { 
  9.         e.printStackTrace(); 
  10.       } catch (IllegalAccessException e) { 
  11.         e.printStackTrace(); 
  12.       } 
  13.     }); 
  14.     ServletRegistration.Dynamic reg = ctx.addServlet("MyServlet", com.pack.servlet.MyServlet.class) ; 
  15.     reg.setLoadOnStartup(1) ; 
  16.     reg.addMapping("/hello") ; 
  17.   } 

注意:@HandlesTypes該注解會(huì)把屬性value配置的值(ScoreWebInt.class)對(duì)應(yīng)的所有類(lèi)都收集上然后在onStartup方法中的Set 集合中應(yīng)用。

在spring-web-xxxx.jar下就有通過(guò)該技術(shù)實(shí)現(xiàn)的相應(yīng)功能。

3 掃描Servlet實(shí)現(xiàn)原理

在方式1中的實(shí)現(xiàn)原理就是掃描類(lèi)路徑下所有@WebServlet,@WebFilter,@WebListener。找到所有的類(lèi)后再通過(guò)方式2的方式進(jìn)行注冊(cè)。下面將核心源碼貼出

3.1 導(dǎo)入核心類(lèi)

  1. // 該注解如果沒(méi)有配置basePackages或者basePackageClasses屬性,那么會(huì)讀取當(dāng)前添加@ServletComponentScan注解的類(lèi)的包路徑進(jìn)行掃描。 
  2. @Target(ElementType.TYPE) 
  3. @Retention(RetentionPolicy.RUNTIME) 
  4. @Documented 
  5. @Import(ServletComponentScanRegistrar.class) 
  6. public @interface ServletComponentScan { 
  7. // 注冊(cè)BeanDefinition 
  8. class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar{ 
  9.   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 
  10.     Set<String> packagesToScan = getPackagesToScan(importingClassMetadata); 
  11.     if (registry.containsBeanDefinition(BEAN_NAME)) { 
  12.       updatePostProcessor(registry, packagesToScan); 
  13.     } else { 
  14.       // 當(dāng)前容器中沒(méi)有對(duì)應(yīng)的Bean時(shí)執(zhí)行該方法   
  15.       addPostProcessor(registry, packagesToScan); 
  16.     } 
  17.   } 

3.2 注冊(cè)BeanFactory 處理器

ServletComponentScanRegistrar最核心的功能就是注冊(cè)BeanFactoryPostProcessor

  1. class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar{ 
  2.   private void addPostProcessor(BeanDefinitionRegistry registry, Set<String> packagesToScan) { 
  3.     GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); 
  4.     beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class); 
  5.     beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(packagesToScan); 
  6.     beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 
  7.     registry.registerBeanDefinition(BEAN_NAME, beanDefinition); 
  8.   } 

3.3 實(shí)例化掃描組件

進(jìn)入

ServletComponentRegisteringPostProcessor類(lèi)中首先這個(gè)類(lèi)有個(gè)static代碼塊

  1. class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcessor, ApplicationContextAware { 
  2.   private static final List<ServletComponentHandler> HANDLERS; 
  3.   static { 
  4.     List<ServletComponentHandler> servletComponentHandlers = new ArrayList<>(); 
  5.     servletComponentHandlers.add(new WebServletHandler()); 
  6.     servletComponentHandlers.add(new WebFilterHandler()); 
  7.     servletComponentHandlers.add(new WebListenerHandler()); 
  8.     HANDLERS = Collections.unmodifiableList(servletComponentHandlers); 
  9.   } 
  10. }     

這段代碼分別是添加相應(yīng)Servlet, Filter, Listener的處理句柄,分別處理@WebServlet,@WebFilter,@WebListener 注解。

查看WebServletHandler

  1. class WebServletHandler extends ServletComponentHandler { 
  2.   WebServletHandler() { 
  3.     super(WebServlet.class); 
  4.   } 
  5.   // 看到該方法也就十分清楚了最終找到所有的Class以后,通過(guò)ServletRegistrationBean進(jìn)行注冊(cè)為Bean 
  6.   @Override 
  7.   public void doHandle(Map<String, Object> attributes, AnnotatedBeanDefinition beanDefinition,BeanDefinitionRegistry registry) { 
  8.     BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServletRegistrationBean.class); 
  9.     builder.addPropertyValue("asyncSupported", attributes.get("asyncSupported")); 
  10.     builder.addPropertyValue("initParameters", extractInitParameters(attributes)); 
  11.     builder.addPropertyValue("loadOnStartup", attributes.get("loadOnStartup")); 
  12.     String name = determineName(attributes, beanDefinition); 
  13.     builder.addPropertyValue("name"name); 
  14.     builder.addPropertyValue("servlet", beanDefinition); 
  15.     builder.addPropertyValue("urlMappings", extractUrlPatterns(attributes)); 
  16.     builder.addPropertyValue("multipartConfig", determineMultipartConfig(beanDefinition)); 
  17.     registry.registerBeanDefinition(name, builder.getBeanDefinition()); 
  18.   } 
  19.   // other code 
  20. }     
  21. // 父類(lèi)ServletComponentHandler;在父類(lèi)總添加相應(yīng)的過(guò)濾器(分別查找相應(yīng)注解的類(lèi),@WebServlet等。) 
  22. abstract class ServletComponentHandler { 
  23.   private final Class<? extends Annotation> annotationType; 
  24.   private final TypeFilter typeFilter; 
  25.   protected ServletComponentHandler(Class<? extends Annotation> annotationType) { 
  26.     this.typeFilter = new AnnotationTypeFilter(annotationType); 
  27.     this.annotationType = annotationType; 
  28.   } 

 接下來(lái)執(zhí)行BeanFactoryPostProcessor對(duì)應(yīng)的回調(diào)方法了

  1. class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcessor, ApplicationContextAware { 
  2.   @Override 
  3.   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
  4.     if (isRunningInEmbeddedWebServer()) { 
  5.       ClassPathScanningCandidateComponentProvider componentProvider = createComponentProvider(); 
  6.       for (String packageToScan : this.packagesToScan) { 
  7.         scanPackage(componentProvider, packageToScan); 
  8.       } 
  9.     } 
  10.   } 

createComponentProvider方法進(jìn)行創(chuàng)建掃描相應(yīng)符合條件的Bean掃描類(lèi)

  1. private ClassPathScanningCandidateComponentProvider createComponentProvider() { 
  2.   ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false); 
  3.   componentProvider.setEnvironment(this.applicationContext.getEnvironment()); 
  4.   componentProvider.setResourceLoader(this.applicationContext); 
  5.   for (ServletComponentHandler handler : HANDLERS) { 
  6.     componentProvider.addIncludeFilter(handler.getTypeFilter()); 
  7.   } 
  8.   return componentProvider; 

在該方法中為當(dāng)前的

ClassPathScanningCandidateComponentProvider類(lèi)掃描設(shè)置過(guò)濾器;過(guò)濾器在上面的static靜態(tài)代碼塊中已經(jīng)設(shè)置了WebServletHandler,WebFilterHandler,WebListenerHandler在父類(lèi)中分別創(chuàng)建不同注解的new AnnotationTypeFilter(annotationType)過(guò)濾類(lèi)。

創(chuàng)建完類(lèi)掃描類(lèi)以后開(kāi)始掃描通過(guò)該類(lèi)掃描相應(yīng)包(路徑)下的所有類(lèi)文件 檢查是否有對(duì)應(yīng)的注解。

3.4 查找及注冊(cè)Bean

  1. class ServletComponentRegisteringPostProcessor implements BeanFactoryPostProcessor, ApplicationContextAware { 
  2.   private void scanPackage(ClassPathScanningCandidateComponentProvider componentProvider, String packageToScan) { 
  3.     for (BeanDefinition candidate : componentProvider.findCandidateComponents(packageToScan)) { 
  4.       if (candidate instanceof AnnotatedBeanDefinition) { 
  5.         for (ServletComponentHandler handler : HANDLERS) { 
  6.           handler.handle(((AnnotatedBeanDefinition) candidate), (BeanDefinitionRegistry) this.applicationContext); 
  7.         } 
  8.       } 
  9.     } 
  10.   } 

findCandidateComponents方法查找候選的(符合條件)的類(lèi)并實(shí)例化為BeanDefinition對(duì)象。

方法執(zhí)行鏈findCandidateComponents ---》scanCandidateComponents

在scanCandidateComponents方法中查找符合條件的類(lèi),然后實(shí)例化為BeanDefinition

  1. public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware { 
  2.   private Set<BeanDefinition> scanCandidateComponents(String basePackage) { 
  3.     Set<BeanDefinition> candidates = new LinkedHashSet<>(); 
  4.     MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); 
  5.     if (isCandidateComponent(metadataReader)) { 
  6.       ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); 
  7.       sbd.setSource(resource); 
  8.       if (isCandidateComponent(sbd)) { 
  9.         candidates.add(sbd); 
  10.       } 
  11.     } 
  12.     return candidates; 
  13.   } 
  14.   protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { 
  15.     for (TypeFilter tf : this.excludeFilters) { 
  16.       if (tf.match(metadataReader, getMetadataReaderFactory())) { 
  17.         return false
  18.       } 
  19.     } 
  20.     for (TypeFilter tf : this.includeFilters) { 
  21.       if (tf.match(metadataReader, getMetadataReaderFactory())) { 
  22.         return isConditionMatch(metadataReader); 
  23.       } 
  24.     } 
  25.     return false
  26.   } 

在第二個(gè)for開(kāi)始匹配所有的類(lèi)是否有相關(guān)的注解。如果匹配上就相應(yīng)的創(chuàng)建BeanDefinition對(duì)象放入集合Set中。

查找到所有的類(lèi)以后分別調(diào)用相應(yīng)的Web*Handler(ServletComponentHandler)進(jìn)行注冊(cè)Bean。

返回到上面的scanPackage方法中執(zhí)行handler.handle方法。

  1. abstract class ServletComponentHandler { 
  2.   void handle(AnnotatedBeanDefinition beanDefinition, BeanDefinitionRegistry registry) { 
  3.     Map<String, Object> attributes = beanDefinition.getMetadata().getAnnotationAttributes(this.annotationType.getName()); 
  4.     if (attributes != null) { 
  5.       doHandle(attributes, beanDefinition, registry); 
  6.     } 
  7.   } 

doHandle方法分別在子類(lèi)(WebServletHandler,WebFilterHandler,WebListenerHandler)中實(shí)現(xiàn),如上面已經(jīng)提到的WebServletHandler類(lèi)的doHandler方法。

到這里我們知道了注解的方式最終也是被注冊(cè)為ServletRegistrationBean 實(shí)例。那這個(gè)ServletRegistrationBean又是如何被容器(Tomcat)所感知的呢?

3.5 Tomcat注冊(cè)Servlet

在Web容器下 BeanFactory使用的是

AnnotationConfigServletWebServerApplicationContext

Spring IOC容器核心方法是refresh方法

  1. public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { 
  2.   public void refresh() throws BeansException, IllegalStateException { 
  3.     synchronized (this.startupShutdownMonitor) { 
  4.       try { 
  5.         // Initialize other special beans in specific context subclasses. 
  6.         onRefresh(); 
  7.       } catch (BeansException ex) { 
  8.         throw ex; 
  9.       } finally { 
  10.         resetCommonCaches(); 
  11.       } 
  12.     } 
  13.   } 
  14. }     

這里只留了onRefresh方法,進(jìn)入該方法:

onRefresh會(huì)進(jìn)入到子類(lèi)的方法

  1. public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext { 
  2.   protected void onRefresh() { 
  3.     super.onRefresh(); 
  4.     try { 
  5.       createWebServer(); 
  6.     } catch (Throwable ex) { 
  7.       throw new ApplicationContextException("Unable to start web server", ex); 
  8.     } 
  9.   } 
  10. }     

 進(jìn)入createWebServer方法

  1. public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext { 
  2.   private void createWebServer() { 
  3.     WebServer webServer = this.webServer; 
  4.     ServletContext servletContext = getServletContext(); 
  5.     if (webServer == null && servletContext == null) { 
  6.       ServletWebServerFactory factory = getWebServerFactory(); 
  7.       this.webServer = factory.getWebServer(getSelfInitializer()); 
  8.       getBeanFactory().registerSingleton("webServerGracefulShutdown",new WebServerGracefulShutdownLifecycle(this.webServer)); 
  9.       getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer)); 
  10.     } else if (servletContext != null) { 
  11.       try { 
  12.         getSelfInitializer().onStartup(servletContext); 
  13.       } catch (ServletException ex) { 
  14.         throw new ApplicationContextException("Cannot initialize servlet context", ex); 
  15.       } 
  16.     } 
  17.     initPropertySources(); 
  18.   } 
  19.  

這里會(huì)進(jìn)入factory.getWebServer(getSelfInitializer())方法執(zhí)行

進(jìn)入getSelfInitializer()方法

  1. public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext { 
  2.   private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() { 
  3.     return this::selfInitialize; 
  4.   } 
  5.  
  6.   private void selfInitialize(ServletContext servletContext) throws ServletException { 
  7.     prepareWebApplicationContext(servletContext); 
  8.     registerApplicationScope(servletContext); 
  9.     WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext); 
  10.     for (ServletContextInitializer beans : getServletContextInitializerBeans()) { 
  11.       beans.onStartup(servletContext); 
  12.     } 
  13.   } 

這里的for循環(huán)是遍歷當(dāng)前容器中所有ServletContextInitializer類(lèi)型的Bean。ServletRegistrationBean就是繼承ServletContextInitializer

到這里分別調(diào)用ServletContextInitializer的onStartup方法,進(jìn)入onStartup方法:

  1. public abstract class RegistrationBean implements ServletContextInitializer, Ordered { 
  2.   @Override 
  3.   public final void onStartup(ServletContext servletContext) throws ServletException { 
  4.     String description = getDescription(); 
  5.     if (!isEnabled()) { 
  6.       logger.info(StringUtils.capitalize(description) + " was not registered (disabled)"); 
  7.       return
  8.     } 
  9.     register(description, servletContext); 
  10.   } 
  11.   // 在子類(lèi)中實(shí)現(xiàn)   
  12.   protected abstract void register(String description, ServletContext servletContext);   

進(jìn)入子類(lèi)DynamicRegistrationBean

  1. public abstract class DynamicRegistrationBean<D extends Registration.Dynamic> extends RegistrationBean { 
  2.   @Override 
  3.   protected final void register(String description, ServletContext servletContext) { 
  4.     D registration = addRegistration(description, servletContext); 
  5.     if (registration == null) { 
  6.       logger.info(StringUtils.capitalize(description) + " was not registered (possibly already registered?)"); 
  7.       return
  8.     } 
  9.     // 配置Servlet Mapping相關(guān)的信息(在子類(lèi)ServletRegistrationBean中實(shí)現(xiàn)的)   
  10.     configure(registration); 
  11.   } 
  12.   // 子類(lèi)中實(shí)現(xiàn) 
  13.   protected abstract D addRegistration(String description, ServletContext servletContext); 

 進(jìn)入子類(lèi)ServletRegistrationBean

  1. public class ServletRegistrationBean<T extends Servlet> extends DynamicRegistrationBean<ServletRegistration.Dynamic> { 
  2.   @Override 
  3.   protected ServletRegistration.Dynamic addRegistration(String description, ServletContext servletContext) { 
  4.     String name = getServletName(); 
  5.     return servletContext.addServlet(name, this.servlet); 
  6.   } 

 到這里就是通過(guò)ServletContext來(lái)動(dòng)態(tài)注冊(cè)Servlet(Servilet3.0)。

這里返回了

ServletRegistration.Dynamic對(duì)象會(huì)繼續(xù)執(zhí)行configure方法配置urlMapping等信息。

  1. public class ServletRegistrationBean<T extends Servlet> extends DynamicRegistrationBean<ServletRegistration.Dynamic> { 
  2.   @Override 
  3.   protected void configure(ServletRegistration.Dynamic registration) { 
  4.     super.configure(registration); 
  5.     String[] urlMapping = StringUtils.toStringArray(this.urlMappings); 
  6.     if (urlMapping.length == 0 && this.alwaysMapUrl) { 
  7.       urlMapping = DEFAULT_MAPPINGS; 
  8.     } 
  9.     if (!ObjectUtils.isEmpty(urlMapping)) { 
  10.       registration.addMapping(urlMapping); 
  11.     } 
  12.     registration.setLoadOnStartup(this.loadOnStartup); 
  13.     if (this.multipartConfig != null) { 
  14.       registration.setMultipartConfig(this.multipartConfig); 
  15.     } 
  16.   } 

到此在Springboot環(huán)境下Servlet如何被注冊(cè)到Servlet容器中就已經(jīng)清晰了。這動(dòng)態(tài)注冊(cè)Servlet的相關(guān)API都是在Servlet3.0規(guī)范中才有的。

 

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2024-05-10 07:44:23

C#進(jìn)程程序

2021-05-07 16:19:36

異步編程Java線程

2024-02-26 08:04:38

ReactReact.js場(chǎng)景

2025-01-21 10:04:40

Java并發(fā)阻塞隊(duì)列

2024-02-05 12:08:07

線程方式管理

2022-05-27 06:57:50

Python循環(huán)方式生成器

2021-08-05 07:28:25

Java實(shí)現(xiàn)方式

2023-04-23 09:50:50

@BeanSpring

2023-04-28 12:37:59

Spring@Bean使用方式

2018-02-08 09:04:58

Nginx404頁(yè)面方法

2019-07-23 17:52:59

Spring BootJava開(kāi)發(fā)

2019-07-23 15:56:56

Spring Boot部署servlet

2023-10-30 11:53:37

繼承JS父類(lèi)

2020-09-07 08:00:48

2023-06-08 08:06:07

error錯(cuò)誤頁(yè)原理

2024-11-04 09:39:08

Java?接口Thread?類(lèi)

2024-06-12 08:05:06

2024-04-24 11:24:43

C#數(shù)據(jù)去重

2023-02-28 09:07:18

ChatGPTAI

2025-03-26 00:35:25

點(diǎn)贊
收藏

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

97se综合| 爽爽视频在线观看| 欧美在线精品一区| 亚洲国模精品私拍| 欧美三级午夜理伦三级富婆| a级毛片免费观看在线| 不卡视频一二三| 国产精品视频1区| 久一视频在线观看| 精品免费在线| 日韩欧美另类在线| 黄色三级视频在线| sm在线观看| |精品福利一区二区三区| 国产日产精品一区二区三区四区| 国产精品成人久久久| 欧美激情91| 中文字幕在线亚洲| 免费a级黄色片| 日韩在线精品强乱中文字幕| 在线观看日韩一区| 欧美成人高潮一二区在线看| 欧美96在线| 国产日产欧美一区| 久久精品日产第一区二区三区乱码| 在线观看黄色国产| 久久精品一本| 91精品国产高清自在线看超| 2018天天弄| 99久久婷婷国产综合精品电影√| 亚洲精品乱码久久久久久按摩观| 三级网站免费看| 国产成人精品一区二区三区视频 | 香蕉亚洲视频| 欧美黑人一级爽快片淫片高清| 蜜桃av免费在线观看| 亚洲三级性片| 国产视频精品免费播放| 男人网站在线观看| 高潮按摩久久久久久av免费| 91麻豆精品国产91久久久资源速度| 免费观看成人网| 中文在线资源| 婷婷亚洲久悠悠色悠在线播放| 在线观看17c| 黄色精品免费看| 国产精品成人免费在线| 日韩性感在线| 黄色片免费在线| 国产欧美一区二区三区在线看蜜臀 | 嫩草伊人久久精品少妇av杨幂| 第一福利永久视频精品 | www.超碰在线| 亚欧色一区w666天堂| 91精品国产91久久久久麻豆 主演| v片在线观看| 亚洲精品高清在线| 日本aa在线观看| 超碰在线cao| 欧美日韩亚洲激情| 国产一区视频免费观看| 欧美日韩精品免费观看视欧美高清免费大片| 日韩欧美999| 中文字幕第80页| 国产精品伦一区二区| 欧美日韩国产不卡| 久久久久久久久久毛片| 亚洲网一区二区三区| 精品国产乱码久久久久久免费| www.欧美com| 奇米影视777在线欧美电影观看| 亚洲二区中文字幕| 国产交换配乱淫视频免费| 九九久久婷婷| 日韩亚洲欧美中文在线| 久青草视频在线观看| 久久激情婷婷| 国产在线98福利播放视频| a在线观看免费| 成人高清在线视频| 色综合久久久久久久久五月| 欧美精品日韩少妇| 亚洲444eee在线观看| 爆乳熟妇一区二区三区霸乳| 国产美女精品视频免费播放软件| 欧美精品一区二区三区蜜桃视频| 国精产品一区一区三区免费视频 | 欧美视频在线观看视频| a一区二区三区| 91精品国产免费| 国产成人无码一区二区在线观看| 欧美日韩国产传媒| 欧美高清videos高潮hd| 中文字幕在线看人| 国产风韵犹存在线视精品| 久久手机视频| 在线不卡日本v二区707| 日本韩国视频一区二区| 久久精品一卡二卡| 国产精品欧美日韩一区| 九九精品视频在线| 国产成人麻豆免费观看| 成人性视频免费网站| 天天综合色天天综合色hd| 欧美日韩在线视频免费观看| 色婷婷亚洲婷婷| 国产人妻精品午夜福利免费| 精品国产一区二区三区噜噜噜 | 尤物精品国产第一福利三区| 欧美日韩成人免费观看| 麻豆精品蜜桃视频网站| 国产伦精品一区二区三区免| 色网站在线看| 色综合网站在线| 91精品国产高清91久久久久久| 狠狠做六月爱婷婷综合aⅴ | 麻豆一区二区三区在线观看| 国产精品久久久久av电视剧| 亚洲第一视频在线观看| tube国产麻豆| 日本午夜精品一区二区三区电影| 国产精品乱码一区二区三区| а√中文在线8| 欧美性大战久久久久久久| 亚洲色偷偷色噜噜狠狠99网| 亚洲xxx拳头交| 国产精品日韩在线| 黄色软件在线| 91久久精品一区二区| 熟女人妻在线视频| 亚洲午夜91| 亚洲在线免费观看| 免费在线观看黄| 欧美日韩免费视频| 少妇愉情理伦三级| 日韩精品国产精品| 日本成人黄色免费看| 日本在线影院| 亚洲精品在线视频| 国产精品乱子伦| 99精品1区2区| 成熟丰满熟妇高潮xxxxx视频| 亚洲不卡在线| 欧美精品www在线观看| 性生活视频软件| 一区二区三区四区国产精品| 999热精品视频| 欧美日韩天堂| 国产精品欧美久久| 国产啊啊啊视频在线观看| 精品第一国产综合精品aⅴ| 免费中文字幕视频| 成人激情免费电影网址| 你懂的av在线| 国产精品一区二区av日韩在线| 日韩美女视频在线观看| 成人午夜影视| 这里是久久伊人| 国产高清在线免费观看| 顶级嫩模精品视频在线看| 丁香花在线影院观看在线播放| 国产suv精品一区| 欧美一级黑人aaaaaaa做受| 男女视频在线观看免费| 欧美午夜精品理论片a级按摩| 夫妇露脸对白88av| 国产精品一级片在线观看| 黄色激情在线视频| 亚洲亚洲免费| 成人免费激情视频| 久草在线新免费首页资源站| 亚洲精品成人网| а中文在线天堂| 亚洲特级片在线| 亚洲国产综合视频| 日韩影院免费视频| 欧美另类videosbestsex日本| 成人福利一区| 国产精品久久97| www在线视频| 精品国产乱码久久久久久夜甘婷婷| 国产成人在线观看网站| 国产精品久久久久久久久免费相片 | 国产69精品久久久久久久久久| 久久久国产一区二区三区四区小说 | 国产这里有精品| 久久久www免费人成精品| 天堂在线一区二区三区| 99精品热视频只有精品10| 亚洲毛片aa| 国内毛片久久| 国产精品视频免费在线观看| 免费电影网站在线视频观看福利| 亚洲人成电影网站| 国内老熟妇对白xxxxhd| 色美美综合视频| 久久一区二区三| 中文一区一区三区高中清不卡| 色婷婷狠狠18禁久久| 日韩av中文字幕一区二区| 99re6这里有精品热视频| 国产91一区| αv一区二区三区| 成人影院在线免费观看| 91精品国产91久久久久| a天堂中文在线官网在线| 亚洲四色影视在线观看| 亚洲成熟女性毛茸茸| 欧美日韩精品是欧美日韩精品| 国产成人无码精品久久久久| 亚洲天堂网中文字| 五月天精品视频| 成人av免费在线| 久久精品久久99| 日本人妖一区二区| 无码人妻h动漫| 伊人久久婷婷| 欧美日韩中文字幕在线播放| 色综合久久网| 日本不卡二区| 亚洲美女久久| 国产一区在线免费观看| 国产精选久久| 成人天堂噜噜噜| 黄页免费欧美| 国产精品青草久久久久福利99| 天堂资源在线| 性色av一区二区三区红粉影视| av毛片在线| 欧美成人在线免费视频| 嫩草香蕉在线91一二三区| 在线精品播放av| 国产日韩精品在线看| 亚洲欧美日本精品| 久久天堂电影| 国产亚洲精品91在线| 欧洲亚洲精品视频| 亚洲精品中文字幕有码专区| 图片区 小说区 区 亚洲五月| 精品国产百合女同互慰| 成人乱码一区二区三区| 精品日产卡一卡二卡麻豆| 精品久久久久成人码免费动漫| 4438x成人网最大色成网站| 国产精品福利电影| 欧美一卡二卡在线| 国产黄a三级三级看三级| 日韩一区二区三免费高清| 超碰在线人人干| 亚洲成人国产精品| 亚洲色偷精品一区二区三区| 精品亚洲一区二区三区| 欧美日本韩国一区二区| 一个人看的www久久| 午夜小视频在线| 久久最新资源网| 免费在线国产视频| 57pao成人国产永久免费| 春暖花开亚洲一区二区三区| 国产精品1区2区在线观看| 免费一级欧美在线观看视频| 91麻豆国产语对白在线观看| 欧美不卡在线观看| 精品国产一区二区三区麻豆小说 | 青青草av网站| 久草在线在线精品观看| 三级网站免费看| 91香蕉视频污在线| 免费看裸体网站| 亚洲视频资源在线| 日韩乱码人妻无码中文字幕| 色婷婷综合视频在线观看| 中文字幕资源网| 日韩欧美一级二级| 欧洲一级在线观看| 久久精品99久久香蕉国产色戒| 日本大片在线播放| 日本欧美精品在线| 国产一区二区| 久久免费看av| 93在线视频精品免费观看| 国产精品第157页| 日日噜噜夜夜狠狠视频欧美人 | 国产午夜精品美女毛片视频| 日日碰狠狠添天天爽| 亚洲国产精品一区二区www在线| 中文字幕在线欧美| 日韩精品一区二区三区在线播放| 亚洲aaa在线观看| 久久久精品一区二区| 天堂а√在线最新版中文在线| 国产剧情久久久久久| 国产亚洲精品美女久久| 亚洲成人午夜在线| 亚洲黄色在线| www.com污| 久久亚洲精华国产精华液| 国产成人自拍网站| 色婷婷激情久久| 国精品人妻无码一区二区三区喝尿| 亚洲天堂av在线免费观看| 久久久123| 成人精品视频99在线观看免费| 神马午夜久久| 精品人妻大屁股白浆无码| 免费欧美日韩国产三级电影| 中文视频在线观看| 亚洲人成人一区二区在线观看| 特级毛片www| 欧美精品一区二区在线观看| 黄色在线播放网站| 国产精品久久久久久久久粉嫩av| 好吊妞视频这里有精品| 中文一区一区三区免费| 日韩精品乱码av一区二区| 少妇户外露出[11p]| 一区二区成人在线| 国产精品探花视频| 尤物九九久久国产精品的特点| 国产精品高颜值在线观看| 91嫩草国产在线观看| 久久精品国产www456c0m| 国产日韩成人内射视频| 久久综合九色综合97婷婷| 亚欧洲精品在线视频| 日韩三级中文字幕| a黄色片在线观看| 91视频免费在线| 久久久久国产精品| 色呦色呦色精品| 中文字幕免费观看一区| 欧美brazzers| 亚洲人成绝费网站色www| 中文在线资源| 欧美综合77777色婷婷| 久久aⅴ国产紧身牛仔裤| 精品人妻一区二区三区香蕉 | 能看的毛片网站| 久久网这里都是精品| 久久久国产精品成人免费| 亚洲激情视频网站| 丝袜老师在线| 欧美中文娱乐网| 丝袜亚洲另类欧美| 国产jjizz一区二区三区视频| 日韩欧美大尺度| 毛片网站在线观看| 国产精品久久久av久久久| 日韩国产欧美一区二区| 亚洲免费999| 亚洲日本在线天堂| 亚洲国产精品久久久久久久| 久久久噜久噜久久综合| 欧美成人午夜77777| 久草精品在线播放| 国产精品欧美极品| 国产精品一区二区av白丝下载| 欧美xxxx做受欧美.88| 成人另类视频| 日本成年人网址| 国产精品毛片久久久久久| 国产美女精品视频国产| 欧美国产日韩xxxxx| 欧美精品密入口播放| 日韩中文字幕免费在线| 亚洲三级免费电影| 老牛影视av牛牛影视av| 人九九综合九九宗合| 国产高清欧美| 催眠调教后宫乱淫校园| 日韩欧美精品中文字幕| 777电影在线观看| 成人黄色在线免费观看| 先锋影音国产一区| 很污很黄的网站| 欧美精品一区二区三区蜜臀| 中老年在线免费视频| 免费在线观看污污视频| 成人黄色在线网站| 国产又粗又猛又爽又| 欧美精品一区二区三区国产精品| 免费萌白酱国产一区二区三区| 免费看黄色一级大片| 夜夜嗨av一区二区三区网页| 青青久在线视频| 91亚洲永久免费精品| 国产农村妇女精品一二区| 一本在线免费视频| 日韩av有码在线| 色狠狠一区二区三区| 黄色一级视频在线播放| 国产精品理论片在线观看| 色婷婷综合视频| 成人www视频在线观看| 99伊人成综合| 亚洲 欧美 变态 另类 综合| 日韩成人高清在线| 欧美电影院免费观看| 日韩精品无码一区二区三区免费| 亚洲精品视频在线观看网站|