3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringMVC 执行流程解析

發布時間:2025/3/12 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringMVC 执行流程解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SpringMVC 執行流程解析

注:SpringMVC 版本 5.2.15


上面這張圖許多人都看過,本文試圖從源碼的角度帶大家分析一下該過程。

1. ContextLoaderListener

首先我們從 ContextLoaderListener 講起,它繼承自 ServletContextListener,用于監聽 Web 應用程序的啟動與停止。ContextLoaderListener 中的 contextInitialized() 方法用于初始化 Web 應用程序上下文。

ContextLoaderListener # contextInitialized

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {.../*** Initialize the root web application context.*/@Overridepublic void contextInitialized(ServletContextEvent event) {initWebApplicationContext(event.getServletContext());}... }

其中又調用了 initWebApplicationContext() 方法初始化 Web 應用程序上下文

ContextLoader # initWebApplicationContext

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {throw new IllegalStateException("Cannot initialize context because there is already a root application context present - " +"check whether you have multiple ContextLoader* definitions in your web.xml!");}servletContext.log("Initializing Spring root WebApplicationContext");Log logger = LogFactory.getLog(ContextLoader.class);if (logger.isInfoEnabled()) {logger.info("Root WebApplicationContext: initialization started");}long startTime = System.currentTimeMillis();try {if (this.context == null) {// 創建并保存應用程序上下文到屬性中this.context = createWebApplicationContext(servletContext);}if (this.context instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;if (!cwac.isActive()) {if (cwac.getParent() == null) {ApplicationContext parent = loadParentContext(servletContext);cwac.setParent(parent);}// 配置并刷新當前 Web 應用程序上下文configureAndRefreshWebApplicationContext(cwac, servletContext);}}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);ClassLoader ccl = Thread.currentThread().getContextClassLoader();if (ccl == ContextLoader.class.getClassLoader()) {currentContext = this.context;}else if (ccl != null) {currentContextPerThread.put(ccl, this.context);}if (logger.isInfoEnabled()) {long elapsedTime = System.currentTimeMillis() - startTime;logger.info("Root WebApplicationContext initialized in " + elapsedTime + " ms");}return this.context;}catch (RuntimeException | Error ex) {logger.error("Context initialization failed", ex);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);throw ex;} }

該方法中調用了 createWebApplicationContext() 方法創建了 Web 應用程序上下文,并調用 configureAndRefreshWebApplicationContext() 方法配置并刷新當前 Web 應用程序上下文。

ContextLoader # configureAndRefreshWebApplicationContext

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {// 為當前 Web 應用程序上下文設置一個 idif (ObjectUtils.identityToString(wac).equals(wac.getId())) {String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);if (idParam != null) {wac.setId(idParam);}else {wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +ObjectUtils.getDisplayString(sc.getContextPath()));}}// 設置 ServletContextwac.setServletContext(sc);String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);if (configLocationParam != null) {wac.setConfigLocation(configLocationParam);}ConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(sc, null);}customizeContext(sc, wac);// 刷新當前應用程序上下文wac.refresh(); }

該方法的主要作用是刷新當前應用程序上下文,實際上就是調用了 AbstractApplicationContext # refresh 方法,也就是我們常講的啟動 IOC 容器,這個方法里的具體內容這里就不講了。

總結:
ContextLoaderListener 的作用是準備好 Web 應用程序上下文,啟動 IOC 容器。

2. DispatcherServlet 初始化邏輯

先看一張 DispatcherServlet 的繼承關系圖

其中 HttpServletBean 有一個 init() 方法,該方法是一個初始化方法

HttpServletBean # init

@Override public final void init() throws ServletException {// 獲取 web.xml 文件中的 <init-param> 中的參數保存到 PropertyValues 中PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);if (!pvs.isEmpty()) {try {// 將 HttpServletBean 對象轉換為 BeanWrapper 對象BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);// 創建一個 ResourceLoader 對象ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());// 注冊屬性編輯器bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));// 初始化 BeanWrapper 對象initBeanWrapper(bw);// 將屬性值保存到 BeanWrapper 中bw.setPropertyValues(pvs, true);}catch (BeansException ex) {if (logger.isErrorEnabled()) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);}throw ex;}}// Let subclasses do whatever initialization they like.initServletBean(); }

該方法中首先嘗試獲取 web.xml 文件中的 init-param 值,如果獲取到的話,則將它保存到 BeanWrapper 中。最后調用了 initServletBean() 方法

FrameworkServlet # initServletBean

@Override protected final void initServletBean() throws ServletException {getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");if (logger.isInfoEnabled()) {logger.info("Initializing Servlet '" + getServletName() + "'");}long startTime = System.currentTimeMillis();try {// 初始化 WebApplicationContextthis.webApplicationContext = initWebApplicationContext();// 空方法,可由子類去具體實現initFrameworkServlet();}catch (ServletException | RuntimeException ex) {logger.error("Context initialization failed", ex);throw ex;}if (logger.isDebugEnabled()) {String value = this.enableLoggingRequestDetails ?"shown which may lead to unsafe logging of potentially sensitive data" :"masked to prevent unsafe logging of potentially sensitive data";logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +"': request parameters and headers will be " + value);}if (logger.isInfoEnabled()) {logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");} }

該方法中主要調用了 initWebApplicationContext() 去初始化 web 應用程序上下文

FrameworkServlet # initWebApplicationContext

protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (this.webApplicationContext != null) {wac = this.webApplicationContext;if (wac instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;if (!cwac.isActive()) {if (cwac.getParent() == null) {cwac.setParent(rootContext);}// 配置并刷新 web 應用程序上下文configureAndRefreshWebApplicationContext(cwac);}}}if (wac == null) {// 去獲取 web 應用程序上下文wac = findWebApplicationContext();}if (wac == null) {// 創建 web 應用程序上下文wac = createWebApplicationContext(rootContext);}if (!this.refreshEventReceived) {synchronized (this.onRefreshMonitor) {// 刷新 web 應用程序上下文onRefresh(wac);}}if (this.publishContext) {String attrName = getServletContextAttributeName();getServletContext().setAttribute(attrName, wac);}return wac; }

該方法主要是去創建一個新的 web 應用程序上下文,然后調用 onRefresh() 方法

FrameworkServlet # onRefresh

@Override protected void onRefresh(ApplicationContext context) {initStrategies(context); }

DispatcherServlet # initStrategies

protected void initStrategies(ApplicationContext context) {// 初始化 文件上傳解析器initMultipartResolver(context);// 初始化 本地化解析器initLocaleResolver(context);// 初始化 主題解析器initThemeResolver(context);// 初始化 處理器映射器initHandlerMappings(context);// 初始化 處理器映射適配器initHandlerAdapters(context);// 初始化 異常解析器initHandlerExceptionResolvers(context);// 初始化 請求獲取視圖名轉換器initRequestToViewNameTranslator(context);// 初始化 視圖解析器initViewResolvers(context);// 初始化 FlashMap 管理器initFlashMapManager(context); }

該方法中初始化了 SpringMVC 的九大組件。我以 initHandlerMappings() 方法為例講解一下,其他組件的獲取方式和它基本相同。

DispatcherServlet # initHandlerMappings

/*** Initialize the HandlerMappings used by this class.* <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,* we default to BeanNameUrlHandlerMapping.*/ private void initHandlerMappings(ApplicationContext context) {this.handlerMappings = null;// 從 ApplicationContext 中去獲取 HandlerMapping// 獲取不到的話去獲取對象名為 handlerMapping 的 HandlerMapping 對象// 再獲取不到的話則注冊默認的 HandlerMappingif (this.detectAllHandlerMappings) {// 從 ApplicationContext 中獲取Map<String, HandlerMapping> matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);if (!matchingBeans.isEmpty()) {this.handlerMappings = new ArrayList<>(matchingBeans.values());AnnotationAwareOrderComparator.sort(this.handlerMappings);}}else {try {// 獲取名為 handlerMapping 的 HandlerMapping 對象HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);this.handlerMappings = Collections.singletonList(hm);}catch (NoSuchBeanDefinitionException ex) {}}if (this.handlerMappings == null) {// 注冊默認的 HandlerMappingthis.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);if (logger.isTraceEnabled()) {logger.trace("No HandlerMappings declared for servlet '" + getServletName() +"': using default strategies from DispatcherServlet.properties");}} }

該方法首先從 ApplicationContext 中去獲取 HandlerMapping,獲取不到的話去獲取對象名為 handlerMapping 的 HandlerMapping 對象,再獲取不到的話則注冊默認的 HandlerMapping。我們看一下這個默認的 HandlerMapping 是怎么獲取的。

DispatcherServlet # getDefaultStrategies

protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {String key = strategyInterface.getName();// 獲取邏輯在這String value = defaultStrategies.getProperty(key);if (value != null) {// 獲取類名String[] classNames = StringUtils.commaDelimitedListToStringArray(value);List<T> strategies = new ArrayList<>(classNames.length);for (String className : classNames) {try {// 創建 Class 對象Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());Object strategy = createDefaultStrategy(context, clazz);strategies.add((T) strategy);}catch (ClassNotFoundException ex) {throw new BeanInitializationException("Could not find DispatcherServlet's default strategy class [" + className +"] for interface [" + key + "]", ex);}catch (LinkageError err) {throw new BeanInitializationException("Unresolvable class definition for DispatcherServlet's default strategy class [" +className + "] for interface [" + key + "]", err);}}return strategies;}else {return new LinkedList<>();} }

可以看到會嘗試從 defaultStrategies 中獲取值。然后將獲取到的值通過 Class.forName() 方法去創建對象。那么我們看一下這個 defaultStrategies 是什么。

private static final Properties defaultStrategies;static {try {ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);}catch (IOException ex) {throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());} } private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";

defaultStrategies 是 DispatcherServlet 中的一個屬性,類型為 Properties 。在 DispatcherServlet 的靜態代碼塊中加載了 DispatcherServlet.properties 文件到了 defaultStrategies 中。

DispatcherServlet.properties

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolverorg.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\org.springframework.web.servlet.function.support.RouterFunctionMappingorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\org.springframework.web.servlet.function.support.HandlerFunctionAdapterorg.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatororg.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

在 DispatcherServlet.properties 中定義了 HandlerMapping、HandlerAdapter、ViewResolver 等類。它們的獲取邏輯是相似的。通過文件中定義的全限定名,然后調用 Class.forName() 方法去創建對象。

3. DispatcherServlet 處理流程

以 get 請求為例。當發送 get 請求時,由 FrameworkServlet # doGet 方法進行處理。

FrameworkServlet # doGet

@Override protected final void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {processRequest(request, response); }

該方法中又調用了 processRequest() 方法

FrameworkServlet # processRequest

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {long startTime = System.currentTimeMillis();Throwable failureCause = null;// 獲取一個 LocaleContext 對象LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();// 構建一個新的 LocaleContext 對象LocaleContext localeContext = buildLocaleContext(request);// 獲取一個 RequestAttributes 對象RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();// 構建一個新的 ServletRequestAttributes 對象ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());// 初始化資源持有者// 將 localeContext 保存到 LocaleContextHolder 中// 將 requestAttributes 保存到 RequestContextHolder 中initContextHolders(request, localeContext, requestAttributes);try {doService(request, response);}catch (ServletException | IOException ex) {failureCause = ex;throw ex;}catch (Throwable ex) {failureCause = ex;throw new NestedServletException("Request processing failed", ex);}finally {resetContextHolders(request, previousLocaleContext, previousAttributes);if (requestAttributes != null) {requestAttributes.requestCompleted();}logResult(request, response, failureCause, asyncManager);publishRequestHandledEvent(request, response, startTime, failureCause);} }

該方法中新建了一個 LocaleContext 對象和一個 ServletRequestAttributes 對象,并保存到了 LocaleContextHolder 與 RequestContextHolder 中。尤其是 RequestContextHolder 對象,我們可以通過它去獲取 HttpServletRequest、HttpServletResponse 等對象。最后調用了 doService() 方法。

DispatcherServlet # doService

@Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {logRequest(request);// 保留 request attributes 的快照Map<String, Object> attributesSnapshot = null;if (WebUtils.isIncludeRequest(request)) {attributesSnapshot = new HashMap<>();Enumeration<?> attrNames = request.getAttributeNames();while (attrNames.hasMoreElements()) {String attrName = (String) attrNames.nextElement();if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {attributesSnapshot.put(attrName, request.getAttribute(attrName));}}}// Make framework objects available to handlers and view objects.request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());if (this.flashMapManager != null) {FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);if (inputFlashMap != null) {request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));}request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);}try {doDispatch(request, response);}finally {if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Restore the original attribute snapshot, in case of an include.if (attributesSnapshot != null) {restoreAttributesAfterInclude(request, attributesSnapshot);}}} }

該方法中又調用了 doDispatch() 方法

DispatcherServlet # doDispatch

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {// 檢查是否是上傳文件的請求processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// 獲取 HandlerExecutionChain // 該方法中確定了用哪個處理器處理當前請求// 并添加了攔截器mappedHandler = getHandler(processedRequest);// 沒有找到合適的處理器if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 獲取 HandlerAdapterHandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// 獲取請求方法String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}// 執行攔截器的前置處理if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 處理請求并返回 ModelAndView 對象mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);// 執行攔截器的后置處理mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {dispatchException = new NestedServletException("Handler dispatch failed", err);}// 處理最終的結果processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {if (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}} }

接下來我們看一下 getHandler() 方法

DispatcherServlet # getHandler

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings != null) {// 遍歷所有的 HandlerMapping 去獲取 HandlerExecutionChain for (HandlerMapping mapping : this.handlerMappings) {HandlerExecutionChain handler = mapping.getHandler(request);if (handler != null) {return handler;}}}return null; }

該方法中遍歷了所有的 HandlerMapping 去獲取 Handler

AbstractHandlerMapping # getHandler

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {// 獲取合適的 HandlerObject handler = getHandlerInternal(request);if (handler == null) {// 沒有找到合適的 Handler,則使用默認的 Handlerhandler = getDefaultHandler();}if (handler == null) {return null;}// 獲取到了該 Handler 的字符串名,則通過字符串名去獲取對應的對象if (handler instanceof String) {String handlerName = (String) handler;handler = obtainApplicationContext().getBean(handlerName);}// 為當前請求添加攔截器HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);if (logger.isTraceEnabled()) {logger.trace("Mapped to " + handler);}else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {logger.debug("Mapped to " + executionChain.getHandler());}if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);config = (config != null ? config.combine(handlerConfig) : handlerConfig);executionChain = getCorsHandlerExecutionChain(request, executionChain, config);}return executionChain; }

該方法中去獲取合適的 Handler,獲取失敗的話,則會使用默認的 Handler。并為該請求添加攔截器。

RequestMappingInfoHandlerMapping # getHandlerInternal

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);try {return super.getHandlerInternal(request);}finally {ProducesRequestCondition.clearMediaTypesAttribute(request);} }

AbstractHandlerMethodMapping # getHandlerInternal

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {// 獲取請求路徑String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);request.setAttribute(LOOKUP_PATH, lookupPath);// 加讀鎖this.mappingRegistry.acquireReadLock();try {// 根據請求路徑獲取對應的 HandlerMethod HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);}finally {// 釋放讀鎖this.mappingRegistry.releaseReadLock();} }

該方法中根據請求路徑去獲取對應的 HandlerMethod

AbstractHandlerMethodMapping # lookupHandlerMethod

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {List<Match> matches = new ArrayList<>();// 根據請求路徑獲取對應的映射List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);if (directPathMatches != null) {// 獲取匹配的映射// 這里面會做一系列的比較// 如:方法名比較、參數比較、請求頭比較等addMatchingMappings(directPathMatches, matches, request);}if (matches.isEmpty()) {// No choice but to go through all mappings...addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);}// 匹配到合適的方法,則從中找到最匹配的方法if (!matches.isEmpty()) {Match bestMatch = matches.get(0);if (matches.size() > 1) {Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));matches.sort(comparator);bestMatch = matches.get(0);if (logger.isTraceEnabled()) {logger.trace(matches.size() + " matching mappings: " + matches);}if (CorsUtils.isPreFlightRequest(request)) {return PREFLIGHT_AMBIGUOUS_MATCH;}Match secondBestMatch = matches.get(1);if (comparator.compare(bestMatch, secondBestMatch) == 0) {Method m1 = bestMatch.handlerMethod.getMethod();Method m2 = secondBestMatch.handlerMethod.getMethod();String uri = request.getRequestURI();throw new IllegalStateException("Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");}}request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);handleMatch(bestMatch.mapping, lookupPath, request);return bestMatch.handlerMethod;}// 沒有找到合適的方法,返回 nullelse {return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);} }

該方法中會去獲取與請求最匹配的方法,獲取不到則返回 null。

這里就已經獲取完 handler 了,也就是一個 HandlerMethod 對象,比如 TestController # test 。我們往下走。

@Controller public class TestController {@GetMapping("/test")public String test() {return "test";} }

DispatcherServlet # getHandlerAdapter

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter;}}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }

該方法就是去找一個對應的 HandlerAdapter,一般是 RequestMappingHandlerAdapter。

AbstractHandlerMethodAdapter # handle

public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return handleInternal(request, response, (HandlerMethod) handler); }

RequestMappingHandlerAdapter # handleInternal

protected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;checkRequest(request);// Execute invokeHandlerMethod in synchronized block if required.if (this.synchronizeOnSession) {HttpSession session = request.getSession(false);if (session != null) {Object mutex = WebUtils.getSessionMutex(session);synchronized (mutex) {mav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No HttpSession available -> no mutex necessarymav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No synchronization on session demanded at all...mav = invokeHandlerMethod(request, response, handlerMethod);}if (!response.containsHeader(HEADER_CACHE_CONTROL)) {if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);}else {prepareResponse(response);}}return mav; }

該方法中調用了 invokeHandlerMethod() 方法

RequestMappingHandlerAdapter # invokeHandlerMethod

protected ModelAndView invokeHandlerMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);try {// 找到 @InitBinder 標注的方法// @InitBinder 與 WebDatabinder 一起使用,用于注冊自定義的屬性編輯器WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);// 找到 @ModelAttribute 標注的方法ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);// 注冊參數解析器if (this.argumentResolvers != null) {invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);}// 注冊返回值解析器if (this.returnValueHandlers != null) {invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);}invocableMethod.setDataBinderFactory(binderFactory);// 注冊參數名發現器invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);ModelAndViewContainer mavContainer = new ModelAndViewContainer();mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));// 調用 @ModelAttribute 標注的方法,保證它在其他方法執行前先被執行modelFactory.initModel(webRequest, mavContainer, invocableMethod);mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);asyncWebRequest.setTimeout(this.asyncRequestTimeout);WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);asyncManager.setTaskExecutor(this.taskExecutor);asyncManager.setAsyncWebRequest(asyncWebRequest);asyncManager.registerCallableInterceptors(this.callableInterceptors);asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);if (asyncManager.hasConcurrentResult()) {Object result = asyncManager.getConcurrentResult();mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];asyncManager.clearConcurrentResult();LogFormatUtils.traceDebug(logger, traceOn -> {String formatted = LogFormatUtils.formatValue(result, !traceOn);return "Resume with async result [" + formatted + "]";});invocableMethod = invocableMethod.wrapConcurrentResult(result);}// 調用該方法invocableMethod.invokeAndHandle(webRequest, mavContainer);if (asyncManager.isConcurrentHandlingStarted()) {return null;}// 返回 ModelAndView 對象return getModelAndView(mavContainer, modelFactory, webRequest);}finally {webRequest.requestCompleted();} }

該方法中會找到并注冊 @InitBinder 標注的方法,找到并調用 @ModelAttribute 標注的的方法。調用 invokeAndHandleI() 方法,最終返回 ModelAndView 對象

ServletInvocableHandlerMethod # invokeAndHandle

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 調用方法并獲取返回值Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);setResponseStatus(webRequest);if (returnValue == null) {if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {disableContentCachingIfNecessary(webRequest);mavContainer.setRequestHandled(true);return;}}else if (StringUtils.hasText(getResponseStatusReason())) {mavContainer.setRequestHandled(true);return;}mavContainer.setRequestHandled(false);Assert.state(this.returnValueHandlers != null, "No return value handlers");try {// 使用對應的 HandlerMethodReturnValueHandler 去處理返回值this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);}catch (Exception ex) {if (logger.isTraceEnabled()) {logger.trace(formatErrorForReturnValue(returnValue), ex);}throw ex;} }

InvocableHandlerMethod # invokeForRequest

public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 獲取形參值Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);if (logger.isTraceEnabled()) {logger.trace("Arguments: " + Arrays.toString(args));}// 調用方法return doInvoke(args); }

InvocableHandlerMethod # getMethodArgumentValues

protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 獲取 MethodParameter 數組MethodParameter[] parameters = getMethodParameters();if (ObjectUtils.isEmpty(parameters)) {return EMPTY_ARGS;}Object[] args = new Object[parameters.length];for (int i = 0; i < parameters.length; i++) {MethodParameter parameter = parameters[i];parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);args[i] = findProvidedArgument(parameter, providedArgs);if (args[i] != null) {continue;}if (!this.resolvers.supportsParameter(parameter)) {throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));}try {// 解析參數args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);}catch (Exception ex) {// Leave stack trace for later, exception may actually be resolved and handled...if (logger.isDebugEnabled()) {String exMsg = ex.getMessage();if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {logger.debug(formatArgumentError(parameter, exMsg));}}throw ex;}}return args; }

該方法中調用了 resolveArgument() 去解析參數

HandlerMethodArgumentResolverComposite # resolveArgument

public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {// 獲取 HandlerMethodArgumentResolver -> RequestParamMethodArgumentResolverHandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);if (resolver == null) {throw new IllegalArgumentException("Unsupported parameter type [" +parameter.getParameterType().getName() + "]. supportsParameter should be called first.");}// 解析參數return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); }

AbstractNamedValueMethodArgumentResolver # resolveArgument

public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);MethodParameter nestedParameter = parameter.nestedIfOptional();Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);if (resolvedName == null) {throw new IllegalArgumentException("Specified name must not resolve to null: [" + namedValueInfo.name + "]");}Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest);if (arg == null) {if (namedValueInfo.defaultValue != null) {arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);}else if (namedValueInfo.required && !nestedParameter.isOptional()) {handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);}arg = handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());}else if ("".equals(arg) && namedValueInfo.defaultValue != null) {arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);}if (binderFactory != null) {WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);try {arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);}catch (ConversionNotSupportedException ex) {throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),namedValueInfo.name, parameter, ex.getCause());}catch (TypeMismatchException ex) {throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),namedValueInfo.name, parameter, ex.getCause());}}handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);return arg; }

AbstractNamedValueMethodArgumentResolver # getNamedValueInfo

private NamedValueInfo getNamedValueInfo(MethodParameter parameter) {// 先從緩存中獲取NamedValueInfo namedValueInfo = this.namedValueInfoCache.get(parameter);// 緩存中獲取不到if (namedValueInfo == null) {// 獲取 @RequestParam 中的 value 屬性值,如果有,則將參數名設置為該值namedValueInfo = createNamedValueInfo(parameter);// 如果沒有使用 @RequestParam 注解或使用了但沒有設置 value 屬性// 則使用 ASM 框架去獲取字節碼來獲取屬性名namedValueInfo = updateNamedValueInfo(parameter, namedValueInfo);this.namedValueInfoCache.put(parameter, namedValueInfo);}return namedValueInfo; }

RequestParamMethodArgumentResolver # createNamedValueInfo

protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {// 根據 @RequestParam 注解去創建 NamedValueInfo // 如果 @RequestParam 中的 value 屬性有值,則設置參數名為該值RequestParam ann = parameter.getParameterAnnotation(RequestParam.class);return (ann != null ? new RequestParamNamedValueInfo(ann) : new RequestParamNamedValueInfo()); }

AbstractNamedValueMethodArgumentResolver # updateNamedValueInfo

private NamedValueInfo updateNamedValueInfo(MethodParameter parameter, NamedValueInfo info) {String name = info.name;if (info.name.isEmpty()) {name = parameter.getParameterName();if (name == null) {throw new IllegalArgumentException("Name for argument of type [" + parameter.getNestedParameterType().getName() +"] not specified, and parameter name information not found in class file either.");}}String defaultValue = (ValueConstants.DEFAULT_NONE.equals(info.defaultValue) ? null : info.defaultValue);return new NamedValueInfo(name, info.required, defaultValue); }

MethodParameter # getParameterName

public String getParameterName() {if (this.parameterIndex < 0) {return null;}ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;if (discoverer != null) {String[] parameterNames = null;if (this.executable instanceof Method) {parameterNames = discoverer.getParameterNames((Method) this.executable);}else if (this.executable instanceof Constructor) {parameterNames = discoverer.getParameterNames((Constructor<?>) this.executable);}if (parameterNames != null) {this.parameterName = parameterNames[this.parameterIndex];}this.parameterNameDiscoverer = null;}return this.parameterName; }

LocalVariableTableParameterNameDiscoverer # getParameterNames

public String[] getParameterNames(Method method) {Method originalMethod = BridgeMethodResolver.findBridgedMethod(method);return doGetParameterNames(originalMethod); }

LocalVariableTableParameterNameDiscoverer # doGetParameterNames

private String[] doGetParameterNames(Executable executable) {Class<?> declaringClass = executable.getDeclaringClass();Map<Executable, String[]> map = this.parameterNamesCache.computeIfAbsent(declaringClass, this::inspectClass);return (map != NO_DEBUG_INFO_MAP ? map.get(executable) : null); }

LocalVariableTableParameterNameDiscoverer # inspectClass

private Map<Executable, String[]> inspectClass(Class<?> clazz) {// 獲取字節碼文件InputStream is = clazz.getResourceAsStream(ClassUtils.getClassFileName(clazz));if (is == null) {if (logger.isDebugEnabled()) {logger.debug("Cannot find '.class' file for class [" + clazz +"] - unable to determine constructor/method parameter names");}return NO_DEBUG_INFO_MAP;}try {ClassReader classReader = new ClassReader(is);Map<Executable, String[]> map = new ConcurrentHashMap<>(32);// ASM 框架提升字節碼文件classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);return map;}catch (IOException ex) {if (logger.isDebugEnabled()) {logger.debug("Exception thrown while reading '.class' file for class [" + clazz +"] - unable to determine constructor/method parameter names", ex);}}catch (IllegalArgumentException ex) {if (logger.isDebugEnabled()) {logger.debug("ASM ClassReader failed to parse class file [" + clazz +"], probably due to a new Java class file version that isn't supported yet " +"- unable to determine constructor/method parameter names", ex);}}finally {try {is.close();}catch (IOException ex) {}}return NO_DEBUG_INFO_MAP; }

走到這一步便是通過 ASM 框架來提升字節碼文件獲取參數名稱了。所以推薦使用 @ReuquestParam 并設置 value 屬性值,這樣可以直接獲取到參數名,避免了 ASM 框架編輯字節碼所帶來的性能消耗。

DispatcherServlet # processDispatchResult

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {boolean errorView = false;if (exception != null) {if (exception instanceof ModelAndViewDefiningException) {logger.debug("ModelAndViewDefiningException encountered", exception);mv = ((ModelAndViewDefiningException) exception).getModelAndView();}else {Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);mv = processHandlerException(request, response, handler, exception);errorView = (mv != null);}}if (mv != null && !mv.wasCleared()) {// 渲染 ModelAndViewrender(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}else {if (logger.isTraceEnabled()) {logger.trace("No view rendering, null ModelAndView returned.");}}if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Concurrent handling started during a forwardreturn;}if (mappedHandler != null) {// Exception (if any) is already handled..mappedHandler.triggerAfterCompletion(request, response, null);} }

本方法中調用了 render() 方法去渲染視圖

DispatcherServlet # render

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {Locale locale =(this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());response.setLocale(locale);View view;String viewName = mv.getViewName();if (viewName != null) {// 根據 viewName 解析出 Viewview = resolveViewName(viewName, mv.getModelInternal(), locale, request);if (view == null) {throw new ServletException("Could not resolve view with name '" + mv.getViewName() +"' in servlet with name '" + getServletName() + "'");}}else {// No need to lookup: the ModelAndView object contains the actual View object.view = mv.getView();if (view == null) {throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +"View object in servlet with name '" + getServletName() + "'");}}// Delegate to the View object for rendering.if (logger.isTraceEnabled()) {logger.trace("Rendering view [" + view + "] ");}try {if (mv.getStatus() != null) {response.setStatus(mv.getStatus().value());}view.render(mv.getModelInternal(), request, response);}catch (Exception ex) {if (logger.isDebugEnabled()) {logger.debug("Error rendering view [" + view + "]", ex);}throw ex;} }

本方法中調用了 resolveViewName() 去獲取 View

DispatcherServlet # resolveViewName

protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,Locale locale, HttpServletRequest request) throws Exception {if (this.viewResolvers != null) {for (ViewResolver viewResolver : this.viewResolvers) {// 使用 ViewResolver 去解析出 ViewView view = viewResolver.resolveViewName(viewName, locale);if (view != null) {return view;}}}return null; }

本方法中找到合適的 ViewResolver 去解析出 View

public View resolveViewName(String viewName, Locale locale) throws Exception {// 是否啟用了緩存功能,默認啟用了if (!isCache()) {return createView(viewName, locale);}else {// 先嘗試從緩存中取 ViewObject cacheKey = getCacheKey(viewName, locale);View view = this.viewAccessCache.get(cacheKey);if (view == null) {synchronized (this.viewCreationCache) {view = this.viewCreationCache.get(cacheKey);if (view == null) {// 緩存中沒有去到,交給子類去創建 Viewview = createView(viewName, locale);if (view == null && this.cacheUnresolved) {view = UNRESOLVED_VIEW;}if (view != null && this.cacheFilter.filter(view, viewName, locale)) {this.viewAccessCache.put(cacheKey, view);this.viewCreationCache.put(cacheKey, view);}}}}else {if (logger.isTraceEnabled()) {logger.trace(formatKey(cacheKey) + "served from cache");}}return (view != UNRESOLVED_VIEW ? view : null);} }

本方法中判斷是否開啟了視圖緩存功能,默認是開啟了的。先嘗試從緩存中取 View,取不到的話則交給子類去創建 View。

UrlBasedViewResolver # createView

@Override protected View createView(String viewName, Locale locale) throws Exception {// 判斷該視圖解析器是否能處理這個視圖// 如果不能的話,交給其他視圖解析器去處理if (!canHandle(viewName, locale)) {return null;}// 檢查前綴是否為 "redirect:"// 有的話則是請求重定向if (viewName.startsWith(REDIRECT_URL_PREFIX)) {// 截取 "redirect:" 后的字符串String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());// 創建重定視圖RedirectView view = new RedirectView(redirectUrl,isRedirectContextRelative(), isRedirectHttp10Compatible());String[] hosts = getRedirectHosts();if (hosts != null) {view.setHosts(hosts);}return applyLifecycleMethods(REDIRECT_URL_PREFIX, view);}// 檢查前綴是否為 "forward:"// 有的話則是請求轉發if (viewName.startsWith(FORWARD_URL_PREFIX)) {String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());InternalResourceView view = new InternalResourceView(forwardUrl);return applyLifecycleMethods(FORWARD_URL_PREFIX, view);}// 如果沒有加這兩個前綴的話,則回調給父類處理// 其實最終的處理結果是跟請求轉發一樣的return super.createView(viewName, locale); }

該方法中會獲取字符串前綴。前綴為 “redirect:” 則是請求重定向,為 “forward:” 則是請求轉發。如果沒有這兩個前綴的話,又回調到父類 AbstractCachingViewResolver # createView 方法中。

AbstractCachingViewResolver # createView

protected View createView(String viewName, Locale locale) throws Exception {return loadView(viewName, locale); }

回調到父類 AbstractCachingViewResolver # createView 方法,并調用了 loadView() 方法

InternalResourceViewResolver # buildView

protected AbstractUrlBasedView buildView(String viewName) throws Exception {// 可以看到,這里創建的 View 類型跟請求轉發的相同InternalResourceView view = (InternalResourceView) super.buildView(viewName);if (this.alwaysInclude != null) {view.setAlwaysInclude(this.alwaysInclude);}view.setPreventDispatchLoop(true);return view; }

本方法中調用了 buildView() 方法創建 View,可以看到,這里創建的 View 類型跟請求轉發的相同

UrlBasedViewResolver # buildView

protected AbstractUrlBasedView buildView(String viewName) throws Exception {Class<?> viewClass = getViewClass();Assert.state(viewClass != null, "No view class");AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(viewClass);// 拼接上前綴和后綴// 可以從 web.xml 文件中獲取view.setUrl(getPrefix() + viewName + getSuffix());view.setAttributesMap(getAttributesMap());String contentType = getContentType();if (contentType != null) {view.setContentType(contentType);}String requestContextAttribute = getRequestContextAttribute();if (requestContextAttribute != null) {view.setRequestContextAttribute(requestContextAttribute);}Boolean exposePathVariables = getExposePathVariables();if (exposePathVariables != null) {view.setExposePathVariables(exposePathVariables);}Boolean exposeContextBeansAsAttributes = getExposeContextBeansAsAttributes();if (exposeContextBeansAsAttributes != null) {view.setExposeContextBeansAsAttributes(exposeContextBeansAsAttributes);}String[] exposedContextBeanNames = getExposedContextBeanNames();if (exposedContextBeanNames != null) {view.setExposedContextBeanNames(exposedContextBeanNames);}return view; }

本方法中將 viewName 拼接了前綴和后綴,獲取到的便是最終的完整路徑。這里并將 View 獲取成功了。

AbstractView # render

public void render(@Nullable Map<String, ?> model, HttpServletRequest request,HttpServletResponse response) throws Exception {if (logger.isDebugEnabled()) {logger.debug("View " + formatViewName() +", model " + (model != null ? model : Collections.emptyMap()) +(this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes));}// 創建并合并屬性到 Map 中// 如:保存到 ModelAndView 或 Model 中的屬性Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);// 準備好 HttpServletResponse 對象prepareResponse(request, response);// 解析出視圖renderMergedOutputModel(mergedModel, getRequestToExpose(request), response); }

該方法中主要是將我們自己保存到 ModelAndView 或 Model 中的屬性轉換為 Map 對象。最后調用 renderMergedOutputModel() 方法。

InternalResourceView # renderMergedOutputModel

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {// 將屬性保存到 request 域中exposeModelAsRequestAttributes(model, request);// Expose helpers as request attributes, if any.exposeHelpers(request);// 確定請求的 urlString dispatcherPath = prepareForRendering(request, response);// 獲取一個請求轉發器RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);if (rd == null) {throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +"]: Check that the corresponding file exists within your web application archive!");}// 是一個 include 請求,jsp 中經常用到,實現 jsp 頁面的復用if (useInclude(request, response)) {response.setContentType(getContentType());if (logger.isDebugEnabled()) {logger.debug("Including [" + getUrl() + "]");}rd.include(request, response);}else {if (logger.isDebugEnabled()) {logger.debug("Forwarding to [" + getUrl() + "]");}// 請求轉發rd.forward(request, response);} }

4. 總結

SpringMVC 處理請求的大致流程就是這樣了。內容有點多,建議最好還是自己 debug 走一遍代碼,梳理出整個脈絡才好。

總結

以上是生活随笔為你收集整理的SpringMVC 执行流程解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

97se亚洲精品一区 | av人摸人人人澡人人超碰下载 | 日本熟妇乱子伦xxxx | 蜜桃臀无码内射一区二区三区 | 乱中年女人伦av三区 | 亚洲一区二区三区四区 | 巨爆乳无码视频在线观看 | 人妻体内射精一区二区三四 | 四虎影视成人永久免费观看视频 | 97夜夜澡人人爽人人喊中国片 | 国产av久久久久精东av | 国产另类ts人妖一区二区 | 亚洲日韩中文字幕在线播放 | 久久综合网欧美色妞网 | 国产深夜福利视频在线 | 国产99久久精品一区二区 | 夫妻免费无码v看片 | 亚洲精品国产a久久久久久 | 荫蒂被男人添的好舒服爽免费视频 | 中文字幕乱码人妻无码久久 | 亚洲一区二区三区香蕉 | 99久久精品无码一区二区毛片 | 国产人妻大战黑人第1集 | 国产suv精品一区二区五 | 国产极品美女高潮无套在线观看 | 亚洲乱亚洲乱妇50p | www国产精品内射老师 | 四虎影视成人永久免费观看视频 | 国产欧美熟妇另类久久久 | 久久久久久a亚洲欧洲av冫 | 日韩欧美成人免费观看 | 任你躁国产自任一区二区三区 | 久久久精品欧美一区二区免费 | 国产成人久久精品流白浆 | 国产成人精品视频ⅴa片软件竹菊 | 亚洲成a人片在线观看无码 | 亚洲色欲色欲天天天www | 欧美日韩在线亚洲综合国产人 | 精品午夜福利在线观看 | 精品水蜜桃久久久久久久 | 国产精品亚洲专区无码不卡 | 亚洲精品国产精品乱码视色 | 性欧美熟妇videofreesex | 国产三级精品三级男人的天堂 | 中国大陆精品视频xxxx | 国产无套粉嫩白浆在线 | 亚洲码国产精品高潮在线 | 呦交小u女精品视频 | 中文字幕无码视频专区 | 最近中文2019字幕第二页 | 无码毛片视频一区二区本码 | 亲嘴扒胸摸屁股激烈网站 | 国产欧美精品一区二区三区 | 在教室伦流澡到高潮hnp视频 | 亚洲日本在线电影 | 无码吃奶揉捏奶头高潮视频 | 久久精品中文字幕一区 | 国产精品久久久 | 一个人看的www免费视频在线观看 | 内射欧美老妇wbb | 国产精品亚洲五月天高清 | 国产精品内射视频免费 | 亚洲国产精品无码一区二区三区 | 樱花草在线社区www | 国产偷自视频区视频 | 99精品国产综合久久久久五月天 | 4hu四虎永久在线观看 | 九九在线中文字幕无码 | 偷窥村妇洗澡毛毛多 | 国产精品久久久久久久影院 | 男人和女人高潮免费网站 | 亚洲国产高清在线观看视频 | 国产一精品一av一免费 | 妺妺窝人体色www婷婷 | 国产精品va在线观看无码 | 色综合视频一区二区三区 | 久久这里只有精品视频9 | 男女下面进入的视频免费午夜 | 久久亚洲精品中文字幕无男同 | 又大又紧又粉嫩18p少妇 | 国产精品无码成人午夜电影 | 欧美性猛交xxxx富婆 | 亚洲精品午夜国产va久久成人 | 国产麻豆精品精东影业av网站 | 欧美激情综合亚洲一二区 | 中文字幕av无码一区二区三区电影 | 国产精品a成v人在线播放 | 影音先锋中文字幕无码 | 亚洲va欧美va天堂v国产综合 | 精品久久久久久人妻无码中文字幕 | 久久精品丝袜高跟鞋 | 久久人妻内射无码一区三区 | 国产亚av手机在线观看 | 久久天天躁狠狠躁夜夜免费观看 | 国产精品永久免费视频 | 日本免费一区二区三区最新 | 成在人线av无码免费 | 夜夜影院未满十八勿进 | 特级做a爰片毛片免费69 | 扒开双腿疯狂进出爽爽爽视频 | 中文字幕人妻无码一夲道 | 久久国产自偷自偷免费一区调 | 色窝窝无码一区二区三区色欲 | 日本欧美一区二区三区乱码 | 丰满少妇弄高潮了www | 中文字幕乱码人妻二区三区 | 亚洲国产成人a精品不卡在线 | 国产人妻精品一区二区三区 | 日本xxxx色视频在线观看免费 | 精品无码av一区二区三区 | 免费乱码人妻系列无码专区 | 学生妹亚洲一区二区 | 久久伊人色av天堂九九小黄鸭 | 99er热精品视频 | 亚洲精品www久久久 | 亚洲国产高清在线观看视频 | 亚洲成色在线综合网站 | 欧洲欧美人成视频在线 | 77777熟女视频在线观看 а天堂中文在线官网 | 国产人妻精品一区二区三区 | 成人亚洲精品久久久久软件 | 国产精品美女久久久久av爽李琼 | 少妇的肉体aa片免费 | 国产又粗又硬又大爽黄老大爷视 | 亚洲精品综合一区二区三区在线 | 中文字幕+乱码+中文字幕一区 | 中文字幕无码乱人伦 | 久久久国产精品无码免费专区 | 亚洲 激情 小说 另类 欧美 | 精品国偷自产在线视频 | 国产精品第一区揄拍无码 | 一个人看的www免费视频在线观看 | 久久久久亚洲精品中文字幕 | 亚洲成a人片在线观看日本 | 亚洲精品久久久久久一区二区 | 国产无套内射久久久国产 | 精品欧洲av无码一区二区三区 | 日本大香伊一区二区三区 | 午夜福利不卡在线视频 | 最新国产乱人伦偷精品免费网站 | 无码国模国产在线观看 | 99久久人妻精品免费一区 | 国产精品久久久久9999小说 | 男女下面进入的视频免费午夜 | 国产9 9在线 | 中文 | 一本久道久久综合狠狠爱 | 中文字幕人妻无码一区二区三区 | 欧美激情综合亚洲一二区 | 日韩精品a片一区二区三区妖精 | 欧洲熟妇色 欧美 | 久精品国产欧美亚洲色aⅴ大片 | 亚洲精品国产a久久久久久 | 丰满人妻一区二区三区免费视频 | 国内精品人妻无码久久久影院 | 曰韩无码二三区中文字幕 | 99精品视频在线观看免费 | 亚洲乱码国产乱码精品精 | 久久综合狠狠综合久久综合88 | 男女爱爱好爽视频免费看 | 国产色xx群视频射精 | 无码人妻av免费一区二区三区 | 两性色午夜视频免费播放 | 精品国产成人一区二区三区 | 成人试看120秒体验区 | 久久久久国色av免费观看性色 | 日本高清一区免费中文视频 | 婷婷五月综合激情中文字幕 | 国产精品内射视频免费 | 婷婷综合久久中文字幕蜜桃三电影 | 国产在线aaa片一区二区99 | 成人试看120秒体验区 | 激情五月综合色婷婷一区二区 | 好男人www社区 | 亚洲精品一区三区三区在线观看 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国语精品一区二区三区 | 中文亚洲成a人片在线观看 | 国产午夜无码视频在线观看 | 欧美性黑人极品hd | 曰韩无码二三区中文字幕 | 欧美精品一区二区精品久久 | 国产办公室秘书无码精品99 | 亚洲精品一区二区三区婷婷月 | 亚洲日韩一区二区 | 好屌草这里只有精品 | 强奷人妻日本中文字幕 | 日本乱偷人妻中文字幕 | 少妇高潮一区二区三区99 | 精品一区二区三区无码免费视频 | 人人妻人人澡人人爽欧美精品 | 国产香蕉97碰碰久久人人 | 性欧美牲交xxxxx视频 | 国产精品久久久久9999小说 | 久久久久久亚洲精品a片成人 | 国产精品无码久久av | 中文字幕无码乱人伦 | 天堂亚洲2017在线观看 | 国产成人无码a区在线观看视频app | 免费无码午夜福利片69 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 日韩精品无码一区二区中文字幕 | 国产午夜福利亚洲第一 | 97夜夜澡人人爽人人喊中国片 | 久久久www成人免费毛片 | 噜噜噜亚洲色成人网站 | 国产色精品久久人妻 | 亚洲日韩乱码中文无码蜜桃臀网站 | 在线观看免费人成视频 | 国产99久久精品一区二区 | 成人片黄网站色大片免费观看 | 国产在线aaa片一区二区99 | 国产精品鲁鲁鲁 | 国产成人精品无码播放 | 好屌草这里只有精品 | 高潮毛片无遮挡高清免费视频 | 兔费看少妇性l交大片免费 | 国产亚洲美女精品久久久2020 | 亚洲区小说区激情区图片区 | 精品国精品国产自在久国产87 | 97久久国产亚洲精品超碰热 | 青春草在线视频免费观看 | 久久精品国产精品国产精品污 | 精品日本一区二区三区在线观看 | 亚洲欧美日韩成人高清在线一区 | 久久国产劲爆∧v内射 | 国产亚洲精品久久久闺蜜 | 中文无码成人免费视频在线观看 | 欧美xxxx黑人又粗又长 | 东京热男人av天堂 | 亚洲日韩av片在线观看 | 国产精品亚洲综合色区韩国 | 国产真实夫妇视频 | 色婷婷香蕉在线一区二区 | 亚洲 日韩 欧美 成人 在线观看 | 国语自产偷拍精品视频偷 | 国产成人无码av片在线观看不卡 | 无码吃奶揉捏奶头高潮视频 | 国产亚洲精品久久久久久久 | 日韩av无码一区二区三区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 熟女俱乐部五十路六十路av | 亚洲欧美色中文字幕在线 | 亚洲国产精品无码一区二区三区 | 成在人线av无码免观看麻豆 | 伊人久久婷婷五月综合97色 | 国产情侣作爱视频免费观看 | 清纯唯美经典一区二区 | 中文无码精品a∨在线观看不卡 | 日本熟妇人妻xxxxx人hd | 夜先锋av资源网站 | 色欲综合久久中文字幕网 | 免费观看又污又黄的网站 | 亚洲天堂2017无码中文 | 精品一区二区三区波多野结衣 | 欧美freesex黑人又粗又大 | 5858s亚洲色大成网站www | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产极品美女高潮无套在线观看 | 欧美三级不卡在线观看 | 国产亚洲精品久久久闺蜜 | 国产av一区二区精品久久凹凸 | 精品国偷自产在线视频 | 扒开双腿疯狂进出爽爽爽视频 | 无码国产乱人伦偷精品视频 | 女人被爽到呻吟gif动态图视看 | 伊在人天堂亚洲香蕉精品区 | 国产后入清纯学生妹 | 六月丁香婷婷色狠狠久久 | 在线观看免费人成视频 | 中文字幕久久久久人妻 | 人妻人人添人妻人人爱 | 风流少妇按摩来高潮 | 久久久久国色av免费观看性色 | 强开小婷嫩苞又嫩又紧视频 | 国产卡一卡二卡三 | 日日摸夜夜摸狠狠摸婷婷 | 欧美黑人乱大交 | 色综合久久88色综合天天 | 国语自产偷拍精品视频偷 | 精品午夜福利在线观看 | 88国产精品欧美一区二区三区 | 人妻与老人中文字幕 | 免费网站看v片在线18禁无码 | 亚洲国产欧美日韩精品一区二区三区 | 精品乱子伦一区二区三区 | 国产97色在线 | 免 | 国产亲子乱弄免费视频 | 岛国片人妻三上悠亚 | 人人澡人摸人人添 | 久久综合给久久狠狠97色 | 鲁一鲁av2019在线 | 天堂在线观看www | а√天堂www在线天堂小说 | 一本一道久久综合久久 | 国产性生交xxxxx无码 | 超碰97人人做人人爱少妇 | 久久久中文字幕日本无吗 | 无码精品人妻一区二区三区av | 亚洲成熟女人毛毛耸耸多 | 亚洲精品一区二区三区在线观看 | 九月婷婷人人澡人人添人人爽 | 日韩人妻无码中文字幕视频 | 51国偷自产一区二区三区 | 国精产品一区二区三区 | 国产女主播喷水视频在线观看 | 中文字幕亚洲情99在线 | www国产亚洲精品久久网站 | 熟妇人妻激情偷爽文 | 一二三四社区在线中文视频 | 欧美精品免费观看二区 | 国产精品无码成人午夜电影 | 国产无遮挡又黄又爽又色 | 成熟女人特级毛片www免费 | 日韩av无码一区二区三区 | 人妻少妇精品久久 | 亚洲高清偷拍一区二区三区 | 天堂在线观看www | 国产成人人人97超碰超爽8 | 亚洲精品成人福利网站 | 国产免费无码一区二区视频 | 久久亚洲精品成人无码 | 国产成人一区二区三区在线观看 | 久久久www成人免费毛片 | 又粗又大又硬又长又爽 | 欧美 丝袜 自拍 制服 另类 | 欧美激情综合亚洲一二区 | 波多野结衣乳巨码无在线观看 | 鲁大师影院在线观看 | 精品久久久久香蕉网 | 午夜无码区在线观看 | 色妞www精品免费视频 | 中国女人内谢69xxxxxa片 | 牛和人交xxxx欧美 | 男女爱爱好爽视频免费看 | 伊人久久大香线蕉亚洲 | 国产成人无码专区 | 精品无码成人片一区二区98 | 欧美35页视频在线观看 | 国产美女极度色诱视频www | 亚洲国产日韩a在线播放 | 亚洲综合无码久久精品综合 | 亚洲理论电影在线观看 | 日本一区二区三区免费播放 | 亚洲春色在线视频 | 欧美日韩色另类综合 | 老司机亚洲精品影院 | 欧美freesex黑人又粗又大 | 欧美性猛交内射兽交老熟妇 | 无码播放一区二区三区 | 老头边吃奶边弄进去呻吟 | 东京热一精品无码av | 久久精品国产99久久6动漫 | 中文字幕人妻无码一区二区三区 | 性欧美videos高清精品 | 日韩亚洲欧美精品综合 | 无遮挡国产高潮视频免费观看 | 亚洲色www成人永久网址 | 亚洲精品国偷拍自产在线观看蜜桃 | 欧美激情内射喷水高潮 | 亚洲人成影院在线观看 | 国产日产欧产精品精品app | 中国女人内谢69xxxx | aⅴ亚洲 日韩 色 图网站 播放 | 国产人妻人伦精品 | 国产精品久久国产精品99 | 久久国产自偷自偷免费一区调 | 亚洲成在人网站无码天堂 | 欧美国产日韩久久mv | 国产精品久久福利网站 | 成人精品视频一区二区三区尤物 | 日日夜夜撸啊撸 | 国产精品va在线观看无码 | 亚洲成a人一区二区三区 | 黑人巨大精品欧美黑寡妇 | 婷婷五月综合缴情在线视频 | 国产精品久久久午夜夜伦鲁鲁 | 国产真实伦对白全集 | 国产97色在线 | 免 | 久久久久久久人妻无码中文字幕爆 | 亚洲欧美国产精品专区久久 | 人妻天天爽夜夜爽一区二区 | 99久久久无码国产aaa精品 | 小鲜肉自慰网站xnxx | 亚洲の无码国产の无码影院 | 欧美丰满熟妇xxxx性ppx人交 | 亚洲色无码一区二区三区 | 女人和拘做爰正片视频 | 熟妇女人妻丰满少妇中文字幕 | 无码午夜成人1000部免费视频 | 亚洲综合伊人久久大杳蕉 | 波多野结衣 黑人 | 国产精品毛片一区二区 | 久久亚洲a片com人成 | 色五月五月丁香亚洲综合网 | 黑人粗大猛烈进出高潮视频 | 国产精品无码永久免费888 | 一个人免费观看的www视频 | 国产特级毛片aaaaaa高潮流水 | 人人澡人人透人人爽 | 亚洲国产精品美女久久久久 | 99re在线播放 | 国产尤物精品视频 | 亚洲精品久久久久中文第一幕 | 亚洲精品美女久久久久久久 | 国产女主播喷水视频在线观看 | 性做久久久久久久久 | 亚洲精品国偷拍自产在线观看蜜桃 | 久精品国产欧美亚洲色aⅴ大片 | 少妇性l交大片 | 久久久国产一区二区三区 | 亚洲男人av天堂午夜在 | 无码一区二区三区在线 | 国产精品久久久久7777 | 婷婷五月综合激情中文字幕 | 未满成年国产在线观看 | 日韩人妻无码中文字幕视频 | 国产成人精品视频ⅴa片软件竹菊 | 麻豆国产人妻欲求不满谁演的 | 成人精品视频一区二区 | 成人免费无码大片a毛片 | 亚洲经典千人经典日产 | 精品久久久久久亚洲精品 | 无套内射视频囯产 | 性欧美videos高清精品 | 熟女少妇人妻中文字幕 | 久久综合香蕉国产蜜臀av | 亚洲一区二区三区偷拍女厕 | 无码免费一区二区三区 | 亚洲a无码综合a国产av中文 | 欧美兽交xxxx×视频 | 性啪啪chinese东北女人 | 人人妻人人澡人人爽人人精品 | 沈阳熟女露脸对白视频 | 男女作爱免费网站 | 亚洲大尺度无码无码专区 | 免费看少妇作爱视频 | 天天综合网天天综合色 | 国产肉丝袜在线观看 | 欧美日韩一区二区三区自拍 | 国产舌乚八伦偷品w中 | 国产成人一区二区三区别 | 国产精品久久久久久无码 | 狠狠噜狠狠狠狠丁香五月 | 人人妻在人人 | 中文字幕日韩精品一区二区三区 | 久久人人爽人人爽人人片ⅴ | 在线播放无码字幕亚洲 | 亚洲无人区一区二区三区 | 四虎国产精品免费久久 | 国产一区二区三区四区五区加勒比 | 成人免费视频一区二区 | 亚洲人亚洲人成电影网站色 | 蜜臀av在线播放 久久综合激激的五月天 | 亚洲国产一区二区三区在线观看 | 99久久久无码国产aaa精品 | 久久久久免费看成人影片 | 丰满岳乱妇在线观看中字无码 | 国产美女精品一区二区三区 | 精品久久久无码中文字幕 | 国产口爆吞精在线视频 | 国产午夜福利亚洲第一 | 国产黄在线观看免费观看不卡 | 中文字幕无码免费久久9一区9 | 在线看片无码永久免费视频 | 偷窥村妇洗澡毛毛多 | 特级做a爰片毛片免费69 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 2020久久香蕉国产线看观看 | 国产精品18久久久久久麻辣 | 日韩在线不卡免费视频一区 | 爱做久久久久久 | 久久久久亚洲精品男人的天堂 | 亚洲精品一区三区三区在线观看 | 久久婷婷五月综合色国产香蕉 | 亚洲日本在线电影 | 日韩视频 中文字幕 视频一区 | 精品无码一区二区三区的天堂 | 久久综合九色综合欧美狠狠 | 成人免费视频视频在线观看 免费 | 国产精品亚洲综合色区韩国 | 少妇性l交大片 | 日韩在线不卡免费视频一区 | 国产香蕉97碰碰久久人人 | 成人亚洲精品久久久久软件 | 男人和女人高潮免费网站 | 国产精品美女久久久久av爽李琼 | 日本在线高清不卡免费播放 | 无码国产乱人伦偷精品视频 | 亚洲一区二区三区无码久久 | 日本爽爽爽爽爽爽在线观看免 | 蜜桃无码一区二区三区 | 免费人成在线视频无码 | 亚洲国产精品美女久久久久 | 亚洲精品一区二区三区大桥未久 | 波多野结衣乳巨码无在线观看 | 亚洲精品一区二区三区在线观看 | 国产精品无码永久免费888 | 国产区女主播在线观看 | 亲嘴扒胸摸屁股激烈网站 | 亚洲精品综合一区二区三区在线 | 亚洲中文字幕无码一久久区 | 国产亚洲精品久久久久久国模美 | 亚洲成a人一区二区三区 | 欧美35页视频在线观看 | 亚洲小说春色综合另类 | 久久精品国产亚洲精品 | 亚洲狠狠婷婷综合久久 | 亚洲精品无码国产 | 乱人伦人妻中文字幕无码久久网 | 国产精品久久久午夜夜伦鲁鲁 | 18无码粉嫩小泬无套在线观看 | 亚洲乱亚洲乱妇50p | 日本又色又爽又黄的a片18禁 | 日韩av无码中文无码电影 | 免费人成网站视频在线观看 | 中文字幕久久久久人妻 | 久久精品成人欧美大片 | 自拍偷自拍亚洲精品10p | 妺妺窝人体色www在线小说 | 国产精品毛多多水多 | 欧美日韩色另类综合 | 日韩亚洲欧美精品综合 | 狠狠综合久久久久综合网 | 亚无码乱人伦一区二区 | 一个人看的视频www在线 | 国产精品无码成人午夜电影 | 高中生自慰www网站 | 亚洲精品欧美二区三区中文字幕 | 久久久精品成人免费观看 | www成人国产高清内射 | 成人女人看片免费视频放人 | 天堂一区人妻无码 | 久久精品中文闷骚内射 | 国产口爆吞精在线视频 | 国产成人无码专区 | 亚洲国产精品无码一区二区三区 | 日日摸日日碰夜夜爽av | 久久久久久九九精品久 | 女人被男人爽到呻吟的视频 | 香港三级日本三级妇三级 | 成人无码精品一区二区三区 | 亚洲精品一区二区三区在线观看 | 日韩在线不卡免费视频一区 | 欧美老妇交乱视频在线观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产精品二区一区二区aⅴ污介绍 | 精品人人妻人人澡人人爽人人 | 久久zyz资源站无码中文动漫 | 熟妇人妻激情偷爽文 | 亚洲午夜无码久久 | 欧美人与物videos另类 | 欧美老人巨大xxxx做受 | 婷婷丁香五月天综合东京热 | 亚洲日韩av一区二区三区四区 | av香港经典三级级 在线 | 久久亚洲日韩精品一区二区三区 | 国产乱人伦av在线无码 | 亚洲aⅴ无码成人网站国产app | 久久精品99久久香蕉国产色戒 | 国产在线无码精品电影网 | 少女韩国电视剧在线观看完整 | 在线播放无码字幕亚洲 | 强奷人妻日本中文字幕 | 午夜精品久久久内射近拍高清 | 日本精品人妻无码免费大全 | 精品国产麻豆免费人成网站 | 成人欧美一区二区三区黑人免费 | 野外少妇愉情中文字幕 | 男人扒开女人内裤强吻桶进去 | 欧美真人作爱免费视频 | 永久免费精品精品永久-夜色 | 欧美成人高清在线播放 | 三上悠亚人妻中文字幕在线 | 99久久99久久免费精品蜜桃 | 内射老妇bbwx0c0ck | 久激情内射婷内射蜜桃人妖 | 无码人妻久久一区二区三区不卡 | 成人一区二区免费视频 | 国产亚洲人成a在线v网站 | 粉嫩少妇内射浓精videos | 一本久久a久久精品vr综合 | 疯狂三人交性欧美 | 又大又紧又粉嫩18p少妇 | 国产区女主播在线观看 | 国产精品亚洲综合色区韩国 | 国产精品沙发午睡系列 | 亚洲成色在线综合网站 | 一本加勒比波多野结衣 | 青草视频在线播放 | 日本乱人伦片中文三区 | 久久久久久久人妻无码中文字幕爆 | 国产真实伦对白全集 | 久久人人爽人人爽人人片ⅴ | 国产又爽又猛又粗的视频a片 | 亚洲自偷自拍另类第1页 | 亚洲午夜无码久久 | 秋霞特色aa大片 | 东京无码熟妇人妻av在线网址 | 福利一区二区三区视频在线观看 | 性啪啪chinese东北女人 | 丰满妇女强制高潮18xxxx | 亚洲中文字幕在线无码一区二区 | 国产精品.xx视频.xxtv | 久久精品视频在线看15 | 亚洲成av人片天堂网无码】 | √8天堂资源地址中文在线 | 国产麻豆精品一区二区三区v视界 | 女人高潮内射99精品 | 奇米影视888欧美在线观看 | 亚洲精品一区三区三区在线观看 | 久久久精品国产sm最大网站 | 77777熟女视频在线观看 а天堂中文在线官网 | 一个人免费观看的www视频 | 日韩人妻无码一区二区三区久久99 | 亚洲s色大片在线观看 | 国产乱人无码伦av在线a | 久久亚洲中文字幕无码 | 久久国内精品自在自线 | 国产亚洲精品久久久久久大师 | 少妇激情av一区二区 | 国产激情无码一区二区app | 日韩人妻少妇一区二区三区 | 亚洲中文字幕乱码av波多ji | 国产av无码专区亚洲awww | 国产美女精品一区二区三区 | 300部国产真实乱 | 欧美熟妇另类久久久久久多毛 | 亚洲日韩中文字幕在线播放 | 成 人影片 免费观看 | 国产成人无码专区 | 亚洲国产精品久久久天堂 | 少妇高潮喷潮久久久影院 | 国产激情综合五月久久 | 亚洲国产精品毛片av不卡在线 | 国产午夜亚洲精品不卡下载 | 中文字幕无线码免费人妻 | 国产精品亚洲lv粉色 | 国产一区二区不卡老阿姨 | 欧美一区二区三区 | 一本久道久久综合婷婷五月 | 性生交大片免费看l | 中文字幕人妻无码一区二区三区 | 精品久久久久香蕉网 | 国产亚洲精品久久久久久 | 青青草原综合久久大伊人精品 | 中文字幕 人妻熟女 | 2020久久超碰国产精品最新 | 伊人久久大香线蕉av一区二区 | 国产午夜亚洲精品不卡下载 | 性开放的女人aaa片 | 久久精品成人欧美大片 | 亚洲自偷自偷在线制服 | 日本乱人伦片中文三区 | 中文字幕无码乱人伦 | 一本一道久久综合久久 | 国产午夜精品一区二区三区嫩草 | 久久97精品久久久久久久不卡 | 午夜福利电影 | 亚洲色欲色欲天天天www | 国产精品久久久久久久9999 | 国产国产精品人在线视 | 荫蒂被男人添的好舒服爽免费视频 | 欧美日韩色另类综合 | 亚洲综合色区中文字幕 | 亚洲欧美日韩综合久久久 | 国产成人无码a区在线观看视频app | 精品一二三区久久aaa片 | 天堂а√在线中文在线 | 99久久精品日本一区二区免费 | 熟女少妇人妻中文字幕 | 亚洲日韩av一区二区三区中文 | 国产在线一区二区三区四区五区 | 亚洲精品欧美二区三区中文字幕 | av香港经典三级级 在线 | 日日躁夜夜躁狠狠躁 | 国产乱人伦av在线无码 | 精品久久久中文字幕人妻 | 无码人中文字幕 | 婷婷六月久久综合丁香 | 99精品国产综合久久久久五月天 | 在线观看国产午夜福利片 | 国产人妻大战黑人第1集 | 2020最新国产自产精品 | 国产 浪潮av性色四虎 | 免费人成在线视频无码 | 日本乱人伦片中文三区 | 精品国产aⅴ无码一区二区 | 日日干夜夜干 | 狠狠色丁香久久婷婷综合五月 | 内射爽无广熟女亚洲 | 欧洲vodafone精品性 | √8天堂资源地址中文在线 | 亚洲色无码一区二区三区 | 中文字幕无线码 | 国产亚洲精品久久久久久久久动漫 | 国产精品美女久久久久av爽李琼 | 荫蒂被男人添的好舒服爽免费视频 | 午夜精品久久久内射近拍高清 | 熟妇人妻无码xxx视频 | 亚洲欧美精品伊人久久 | 国产xxx69麻豆国语对白 | 熟妇人妻激情偷爽文 | 成人免费视频视频在线观看 免费 | 无套内射视频囯产 | 无码人妻黑人中文字幕 | 亚洲日韩av一区二区三区中文 | 精品 日韩 国产 欧美 视频 | 中文字幕 人妻熟女 | 日韩亚洲欧美中文高清在线 | 美女毛片一区二区三区四区 | 国产午夜亚洲精品不卡 | 曰韩少妇内射免费播放 | 久久人人爽人人爽人人片av高清 | 亚洲熟悉妇女xxx妇女av | 人妻少妇精品久久 | 国产99久久精品一区二区 | 久久五月精品中文字幕 | 国产性生交xxxxx无码 | 55夜色66夜色国产精品视频 | 国产农村妇女高潮大叫 | 亚洲精品中文字幕 | 人妻中文无码久热丝袜 | 免费乱码人妻系列无码专区 | 人人妻在人人 | 久久精品中文字幕一区 | 久久99国产综合精品 | 国产欧美精品一区二区三区 | 欧美精品在线观看 | 成熟妇人a片免费看网站 | 欧美第一黄网免费网站 | 国产精品久久久久久亚洲影视内衣 | 3d动漫精品啪啪一区二区中 | 小sao货水好多真紧h无码视频 | 九九久久精品国产免费看小说 | 国产精品人人妻人人爽 | 99精品视频在线观看免费 | 青青青爽视频在线观看 | 国产三级精品三级男人的天堂 | 国产午夜亚洲精品不卡下载 | 天堂亚洲免费视频 | 漂亮人妻洗澡被公强 日日躁 | 久久久国产一区二区三区 | 国产深夜福利视频在线 | 国内丰满熟女出轨videos | 99久久无码一区人妻 | 精品亚洲韩国一区二区三区 | 国产综合久久久久鬼色 | 久久精品中文字幕大胸 | 久久精品人人做人人综合试看 | 久久综合色之久久综合 | 国产农村乱对白刺激视频 | 国产午夜福利亚洲第一 | 色婷婷综合激情综在线播放 | 青青久在线视频免费观看 | 中文字幕人成乱码熟女app | 又色又爽又黄的美女裸体网站 | 女人高潮内射99精品 | 久久国产精品_国产精品 | 国产绳艺sm调教室论坛 | 少妇久久久久久人妻无码 | 东京热无码av男人的天堂 | √天堂中文官网8在线 | 久久无码中文字幕免费影院蜜桃 | 妺妺窝人体色www在线小说 | 亚洲国产精品久久久久久 | 2020久久超碰国产精品最新 | 97夜夜澡人人爽人人喊中国片 | 久久久久免费看成人影片 | 初尝人妻少妇中文字幕 | 亚洲男人av香蕉爽爽爽爽 | 欧美国产日韩亚洲中文 | 日韩欧美中文字幕在线三区 | 国产成人精品一区二区在线小狼 | 精品aⅴ一区二区三区 | 国产激情精品一区二区三区 | 熟妇人妻无乱码中文字幕 | 欧美xxxxx精品 | 久久久久国色av免费观看性色 | 麻花豆传媒剧国产免费mv在线 | 初尝人妻少妇中文字幕 | 色五月五月丁香亚洲综合网 | 欧美猛少妇色xxxxx | 特黄特色大片免费播放器图片 | 又大又硬又爽免费视频 | 久久久精品国产sm最大网站 | 内射白嫩少妇超碰 | 对白脏话肉麻粗话av | 亚洲国产av美女网站 | 亚洲熟妇色xxxxx欧美老妇y | 久久精品人妻少妇一区二区三区 | 又黄又爽又色的视频 | 奇米影视888欧美在线观看 | 亚洲码国产精品高潮在线 | 97夜夜澡人人双人人人喊 | 骚片av蜜桃精品一区 | 国语精品一区二区三区 | 亚洲一区二区三区含羞草 | 国产精品无码久久av | 永久免费精品精品永久-夜色 | av人摸人人人澡人人超碰下载 | 高中生自慰www网站 | 欧美人与善在线com | 无码人妻av免费一区二区三区 | 国产综合久久久久鬼色 | 亚洲 激情 小说 另类 欧美 | 欧美日韩视频无码一区二区三 | 无码国产色欲xxxxx视频 | 精品国产一区av天美传媒 | 成人免费视频视频在线观看 免费 | 国产激情一区二区三区 | 国产日产欧产精品精品app | 成在人线av无码免费 | 六月丁香婷婷色狠狠久久 | 夜夜夜高潮夜夜爽夜夜爰爰 | 狠狠色丁香久久婷婷综合五月 | 激情五月综合色婷婷一区二区 | 久久aⅴ免费观看 | 青青草原综合久久大伊人精品 | 国产办公室秘书无码精品99 | 日本精品人妻无码免费大全 | 欧美人与牲动交xxxx | 少妇太爽了在线观看 | 久久婷婷五月综合色国产香蕉 | 在线精品国产一区二区三区 | 精品aⅴ一区二区三区 | 亚洲综合色区中文字幕 | 欧美成人免费全部网站 | 人妻天天爽夜夜爽一区二区 | 国产午夜精品一区二区三区嫩草 | 天堂亚洲免费视频 | 久久视频在线观看精品 | 国产99久久精品一区二区 | 久久精品国产99精品亚洲 | 夫妻免费无码v看片 | 免费无码一区二区三区蜜桃大 | 思思久久99热只有频精品66 | 欧美人与禽猛交狂配 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 波多野结衣aⅴ在线 | 色情久久久av熟女人妻网站 | 一本一道久久综合久久 | 日本熟妇浓毛 | 波多野42部无码喷潮在线 | 精品国产一区av天美传媒 | 亚洲小说图区综合在线 | 中国女人内谢69xxxx | 精品一二三区久久aaa片 | 国产熟女一区二区三区四区五区 | 精品人妻人人做人人爽 | 蜜臀av无码人妻精品 | 天天av天天av天天透 | 欧美国产日韩久久mv | 麻豆果冻传媒2021精品传媒一区下载 | 色欲久久久天天天综合网精品 | 国产精品18久久久久久麻辣 | 精品欧洲av无码一区二区三区 | 精品无人区无码乱码毛片国产 | 女人色极品影院 | 日本丰满护士爆乳xxxx | 亚洲精品综合一区二区三区在线 | 国产成人无码av片在线观看不卡 | 中文字幕+乱码+中文字幕一区 | 男女下面进入的视频免费午夜 | 麻豆国产人妻欲求不满 | 天干天干啦夜天干天2017 | 亚洲gv猛男gv无码男同 | 国产亚洲精品久久久ai换 | 欧美老妇交乱视频在线观看 | 99riav国产精品视频 | 亚欧洲精品在线视频免费观看 | 久久综合狠狠综合久久综合88 | 国产人妻人伦精品 | 国产成人精品久久亚洲高清不卡 | 国产精品视频免费播放 | 亚洲国产精品美女久久久久 | 久久精品女人的天堂av | 丰满妇女强制高潮18xxxx | 久久99精品久久久久久动态图 | 婷婷色婷婷开心五月四房播播 | 欧美一区二区三区 | 国产精品欧美成人 | 日韩av激情在线观看 | 中文字幕人妻无码一夲道 | 亚洲熟妇色xxxxx欧美老妇 | 国产香蕉尹人综合在线观看 | 天堂а√在线地址中文在线 | 精品偷拍一区二区三区在线看 | 国产真人无遮挡作爱免费视频 | 久9re热视频这里只有精品 | 国产精品福利视频导航 | 精品无人国产偷自产在线 | 亚洲国产欧美日韩精品一区二区三区 | 一本色道久久综合亚洲精品不卡 | 丰满少妇女裸体bbw | 免费播放一区二区三区 | 99久久婷婷国产综合精品青草免费 | 3d动漫精品啪啪一区二区中 | 婷婷五月综合缴情在线视频 | 亚洲男人av香蕉爽爽爽爽 | 国产suv精品一区二区五 | 亚洲人成网站色7799 | 丰满少妇高潮惨叫视频 | 人人妻人人澡人人爽精品欧美 | 婷婷丁香五月天综合东京热 | 熟女少妇人妻中文字幕 | 亚洲日韩精品欧美一区二区 | 小sao货水好多真紧h无码视频 | 麻豆md0077饥渴少妇 | 精品国产乱码久久久久乱码 | 性欧美videos高清精品 | 扒开双腿吃奶呻吟做受视频 | 欧美 丝袜 自拍 制服 另类 | 中国女人内谢69xxxx | 色综合天天综合狠狠爱 | 精品aⅴ一区二区三区 | 国产亚洲精品久久久久久大师 | 少妇被黑人到高潮喷出白浆 | 高清无码午夜福利视频 | 三上悠亚人妻中文字幕在线 | 国内精品九九久久久精品 | 久久99精品久久久久久 | 国产精品va在线播放 | 亚洲国产午夜精品理论片 | 免费国产黄网站在线观看 | 国产亚洲视频中文字幕97精品 | 久久午夜无码鲁丝片秋霞 | 98国产精品综合一区二区三区 | 久久视频在线观看精品 | 亚洲国产欧美日韩精品一区二区三区 | 成人免费视频一区二区 | 欧美激情内射喷水高潮 | 国产av人人夜夜澡人人爽麻豆 | 国产人妻精品一区二区三区 | 国产超碰人人爽人人做人人添 | 国产真实伦对白全集 | 国产凸凹视频一区二区 | 少妇激情av一区二区 | 国产肉丝袜在线观看 | 99久久婷婷国产综合精品青草免费 | 又湿又紧又大又爽a视频国产 | 国产精品毛多多水多 | 一个人免费观看的www视频 | 日韩精品无码一区二区中文字幕 | 精品人妻人人做人人爽 | 欧美日韩一区二区综合 | 欧美精品无码一区二区三区 | 红桃av一区二区三区在线无码av | 精品欧美一区二区三区久久久 | 精品国产一区二区三区四区 | www国产亚洲精品久久久日本 | 日韩在线不卡免费视频一区 | 在线播放免费人成毛片乱码 | 国产办公室秘书无码精品99 | 国产精品久久久午夜夜伦鲁鲁 | 欧美日本免费一区二区三区 | 无码国产乱人伦偷精品视频 | 超碰97人人射妻 | 亚洲日韩精品欧美一区二区 | 漂亮人妻洗澡被公强 日日躁 | 成人欧美一区二区三区黑人 | 久久久久成人精品免费播放动漫 | 免费无码肉片在线观看 | 亚洲成熟女人毛毛耸耸多 | 亚洲自偷自偷在线制服 | 中文字幕乱码亚洲无线三区 | 亚洲精品午夜国产va久久成人 | 国产精品毛片一区二区 | 婷婷六月久久综合丁香 | 亚洲の无码国产の无码影院 | 日韩亚洲欧美精品综合 | 免费男性肉肉影院 | 国产成人无码a区在线观看视频app | 秋霞成人午夜鲁丝一区二区三区 | 老司机亚洲精品影院无码 | 香港三级日本三级妇三级 | 久久精品人人做人人综合试看 | 成人无码精品1区2区3区免费看 | 久久亚洲中文字幕精品一区 | 国产高清不卡无码视频 | 欧美性猛交xxxx富婆 | 高潮毛片无遮挡高清免费视频 | 丰满妇女强制高潮18xxxx | 欧美zoozzooz性欧美 | 国产成人无码一二三区视频 | 亚洲欧洲无卡二区视頻 | 99久久久国产精品无码免费 | 超碰97人人做人人爱少妇 | 欧美喷潮久久久xxxxx | 天天躁日日躁狠狠躁免费麻豆 | 中文字幕无码av波多野吉衣 | 欧美国产日韩亚洲中文 | 无码国产乱人伦偷精品视频 | 亚洲gv猛男gv无码男同 | 精品国偷自产在线视频 | 好爽又高潮了毛片免费下载 | 精品久久综合1区2区3区激情 | 欧美黑人乱大交 | 无码国产乱人伦偷精品视频 | 亚洲日韩av一区二区三区四区 | 国产亚洲精品久久久ai换 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 丝袜 中出 制服 人妻 美腿 | 久久综合网欧美色妞网 | 精品无码国产自产拍在线观看蜜 | 中文字幕无码日韩欧毛 | 精品一二三区久久aaa片 | 精品aⅴ一区二区三区 | 国产精品美女久久久久av爽李琼 | 乌克兰少妇性做爰 | 日韩av无码一区二区三区不卡 | 亚洲成av人片天堂网无码】 | 无码人妻出轨黑人中文字幕 | 精品国产一区二区三区四区在线看 | 亚洲一区二区三区国产精华液 | 九九热爱视频精品 | 国产人妖乱国产精品人妖 | 色噜噜亚洲男人的天堂 | 国产片av国语在线观看 | 亚洲第一无码av无码专区 | 亚洲va中文字幕无码久久不卡 | 色狠狠av一区二区三区 | 久久精品国产日本波多野结衣 | 永久免费观看美女裸体的网站 | 国产精品久久久久久久9999 | 精品国偷自产在线视频 | 少妇无码一区二区二三区 | 久久99精品久久久久久 | 国产无遮挡又黄又爽免费视频 | 久久精品无码一区二区三区 | 国产在线一区二区三区四区五区 | 女人和拘做爰正片视频 | 日本一卡二卡不卡视频查询 | 午夜精品一区二区三区的区别 | 精品成在人线av无码免费看 | 女人色极品影院 | 亚洲国产精品久久久天堂 | 亚洲国产精品毛片av不卡在线 | 日本欧美一区二区三区乱码 | 色妞www精品免费视频 | 亚洲午夜福利在线观看 | 国产精品久久久久久亚洲毛片 | 亚洲乱码中文字幕在线 | a在线亚洲男人的天堂 | 亚洲最大成人网站 | 国模大胆一区二区三区 | 日韩精品一区二区av在线 | 精品无码国产自产拍在线观看蜜 | 少妇高潮喷潮久久久影院 | 久久精品人人做人人综合 | 国产深夜福利视频在线 | 俺去俺来也www色官网 | 亚洲中文字幕乱码av波多ji | 老子影院午夜精品无码 | 5858s亚洲色大成网站www | 国产精品久久久一区二区三区 | 亚洲一区二区三区在线观看网站 | 国内精品人妻无码久久久影院蜜桃 | 亚洲日本一区二区三区在线 | 好爽又高潮了毛片免费下载 | 中文字幕无码日韩专区 | 精品无码国产一区二区三区av | 久久人人97超碰a片精品 | 欧洲vodafone精品性 | 欧美成人午夜精品久久久 | 丝袜 中出 制服 人妻 美腿 | 色诱久久久久综合网ywww | 偷窥村妇洗澡毛毛多 | 国产人妻久久精品二区三区老狼 | 沈阳熟女露脸对白视频 | 中文字幕乱码人妻无码久久 | 婷婷五月综合缴情在线视频 | 一二三四社区在线中文视频 | 国产精品二区一区二区aⅴ污介绍 | av无码不卡在线观看免费 | 国产精品二区一区二区aⅴ污介绍 | 精品久久综合1区2区3区激情 | 久久天天躁夜夜躁狠狠 | 国产无遮挡又黄又爽免费视频 | 国产另类ts人妖一区二区 | 亚洲成av人在线观看网址 | 99久久久无码国产aaa精品 | 国产成人综合在线女婷五月99播放 | 久久天天躁狠狠躁夜夜免费观看 | 国产成人无码午夜视频在线观看 | 欧美熟妇另类久久久久久不卡 | 九月婷婷人人澡人人添人人爽 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 人人澡人人透人人爽 | 久久精品一区二区三区四区 | 蜜桃臀无码内射一区二区三区 | 午夜性刺激在线视频免费 | 国产成人无码区免费内射一片色欲 | 无码精品人妻一区二区三区av | 永久免费观看美女裸体的网站 | 欧美亚洲日韩国产人成在线播放 | 国产成人人人97超碰超爽8 | 精品久久久久久人妻无码中文字幕 | 久久国产36精品色熟妇 | 久久综合给合久久狠狠狠97色 | 丝袜人妻一区二区三区 | 久久精品99久久香蕉国产色戒 | 在线看片无码永久免费视频 | 在线视频网站www色 | 久久精品国产日本波多野结衣 | 性史性农村dvd毛片 | 国产99久久精品一区二区 | 久久国产精品二国产精品 | 人人妻人人澡人人爽人人精品浪潮 | 国产精品美女久久久网av | 麻花豆传媒剧国产免费mv在线 | 性色av无码免费一区二区三区 | 亚洲男人av天堂午夜在 | 人妻少妇精品视频专区 | 夜夜高潮次次欢爽av女 | 中文字幕无码人妻少妇免费 | 亚洲中文字幕成人无码 | 国产成人无码av片在线观看不卡 | 亚洲人成影院在线观看 | 国产性生交xxxxx无码 | 一本久道久久综合婷婷五月 | 国产色在线 | 国产 | 无码人中文字幕 | 男女超爽视频免费播放 | 成人无码影片精品久久久 | 真人与拘做受免费视频一 | 欧美日韩色另类综合 | 又湿又紧又大又爽a视频国产 | 夜夜躁日日躁狠狠久久av | 亚洲欧美国产精品久久 | 一区二区三区高清视频一 | 亚洲成在人网站无码天堂 | 国产成人无码区免费内射一片色欲 | 少女韩国电视剧在线观看完整 | 精品少妇爆乳无码av无码专区 | 国产亚洲精品精品国产亚洲综合 | 亚洲国产精品久久久久久 | 国产人妻人伦精品1国产丝袜 | 亚洲日本va午夜在线电影 | 亚洲爆乳大丰满无码专区 | 亚洲va中文字幕无码久久不卡 | 精品熟女少妇av免费观看 | 国内揄拍国内精品人妻 | 亚洲日韩中文字幕在线播放 | 中文字幕乱码人妻无码久久 | 男人扒开女人内裤强吻桶进去 | 国产成人午夜福利在线播放 | aⅴ亚洲 日韩 色 图网站 播放 | 国产精品第一国产精品 | 亚洲精品综合五月久久小说 | 亚洲中文字幕无码一久久区 | 熟女少妇人妻中文字幕 | 欧美日韩色另类综合 | 中文字幕人成乱码熟女app | 国产一区二区三区四区五区加勒比 | 欧美野外疯狂做受xxxx高潮 | 扒开双腿疯狂进出爽爽爽视频 | 国产成人无码a区在线观看视频app | 女人被爽到呻吟gif动态图视看 | 欧美真人作爱免费视频 | 99在线 | 亚洲 | 天天综合网天天综合色 | 久久久久se色偷偷亚洲精品av | 亚洲狠狠婷婷综合久久 | 久久99久久99精品中文字幕 | 国产三级精品三级男人的天堂 | 国产三级精品三级男人的天堂 | 未满成年国产在线观看 | 亚洲一区av无码专区在线观看 | 在线 国产 欧美 亚洲 天堂 | 18精品久久久无码午夜福利 | 疯狂三人交性欧美 | 欧美丰满老熟妇xxxxx性 | 暴力强奷在线播放无码 | 人妻有码中文字幕在线 | 国产精品久久久 | 乱人伦人妻中文字幕无码 | 无码吃奶揉捏奶头高潮视频 | 亚洲人成网站免费播放 | 亚洲 另类 在线 欧美 制服 | av香港经典三级级 在线 | 无码乱肉视频免费大全合集 | 狠狠综合久久久久综合网 | av在线亚洲欧洲日产一区二区 | 成人免费无码大片a毛片 | 国产精品欧美成人 | 国内精品人妻无码久久久影院蜜桃 | 亚洲熟妇色xxxxx亚洲 | 久久精品国产精品国产精品污 | 99精品国产综合久久久久五月天 | 中文字幕亚洲情99在线 | 天天躁夜夜躁狠狠是什么心态 | 日本va欧美va欧美va精品 | 精品无码成人片一区二区98 | 婷婷色婷婷开心五月四房播播 | 国产激情精品一区二区三区 | 九九在线中文字幕无码 | 国产人妻精品午夜福利免费 | 国产乱人偷精品人妻a片 | 思思久久99热只有频精品66 | 扒开双腿吃奶呻吟做受视频 | 麻豆av传媒蜜桃天美传媒 | 成人免费视频视频在线观看 免费 | 久久97精品久久久久久久不卡 | 牲欲强的熟妇农村老妇女视频 | 婷婷六月久久综合丁香 | 亚洲日韩乱码中文无码蜜桃臀网站 | 99久久婷婷国产综合精品青草免费 | 成人欧美一区二区三区 | 99在线 | 亚洲 | 久久这里只有精品视频9 | 免费观看的无遮挡av | 欧美老妇与禽交 | 四虎影视成人永久免费观看视频 | 国产 浪潮av性色四虎 | 亚洲精品国产a久久久久久 | 偷窥日本少妇撒尿chinese | 性色欲情网站iwww九文堂 | 99久久久国产精品无码免费 | 少妇高潮一区二区三区99 | 国产精品美女久久久久av爽李琼 | 亚洲国产精品美女久久久久 | 国产精品美女久久久久av爽李琼 | 天海翼激烈高潮到腰振不止 | 强开小婷嫩苞又嫩又紧视频 | 亚洲啪av永久无码精品放毛片 | 一区二区传媒有限公司 | 国产精品无码mv在线观看 | 精品久久久久久人妻无码中文字幕 | 无码人妻丰满熟妇区五十路百度 | 丰满少妇熟乱xxxxx视频 | 久久视频在线观看精品 | 久久综合久久自在自线精品自 | 丰满人妻被黑人猛烈进入 | 亚洲精品一区二区三区在线观看 | 欧美性生交xxxxx久久久 | 中文字幕乱码亚洲无线三区 | 人人澡人人透人人爽 | 国产精品久久久久影院嫩草 | 亚洲一区av无码专区在线观看 | 99国产欧美久久久精品 | 熟女体下毛毛黑森林 | 国产九九九九九九九a片 | 中文字幕乱码人妻无码久久 | 久久国语露脸国产精品电影 | 久久无码专区国产精品s | 成熟妇人a片免费看网站 | 欧美精品无码一区二区三区 | 亚洲熟悉妇女xxx妇女av | 久久精品丝袜高跟鞋 | 亚洲日韩精品欧美一区二区 | 国产成人精品三级麻豆 | 精品欧洲av无码一区二区三区 | 97夜夜澡人人双人人人喊 | 国产精品久久久久久久9999 | 亚洲乱码日产精品bd | 巨爆乳无码视频在线观看 | 久久午夜无码鲁丝片午夜精品 | 一本久道久久综合婷婷五月 | 天堂无码人妻精品一区二区三区 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 成人精品一区二区三区中文字幕 | 99riav国产精品视频 | 狠狠躁日日躁夜夜躁2020 | 小sao货水好多真紧h无码视频 | 久久亚洲中文字幕精品一区 | 黑人巨大精品欧美黑寡妇 | 色五月五月丁香亚洲综合网 | 好男人www社区 | 国产精品-区区久久久狼 | 东京一本一道一二三区 | 国产色在线 | 国产 | 久久久久亚洲精品男人的天堂 | 久久久国产一区二区三区 | 国产三级久久久精品麻豆三级 | 免费观看又污又黄的网站 | 女高中生第一次破苞av | 少妇激情av一区二区 | 狠狠躁日日躁夜夜躁2020 | 无码av岛国片在线播放 | 人妻插b视频一区二区三区 | 青草视频在线播放 | 男人的天堂av网站 | 日本www一道久久久免费榴莲 | 婷婷综合久久中文字幕蜜桃三电影 | 欧美日本精品一区二区三区 | 亚洲va欧美va天堂v国产综合 | 色婷婷综合激情综在线播放 | 熟女少妇在线视频播放 | 无码av最新清无码专区吞精 | 无码av岛国片在线播放 | 色噜噜亚洲男人的天堂 | 亚洲中文字幕无码中字 | 成 人影片 免费观看 | 人人妻人人澡人人爽欧美精品 | 日日碰狠狠躁久久躁蜜桃 | 国产片av国语在线观看 | 日本肉体xxxx裸交 | 日本丰满护士爆乳xxxx | 无码人妻少妇伦在线电影 | 色偷偷人人澡人人爽人人模 | 久久精品一区二区三区四区 | 人妻无码久久精品人妻 | 久久久成人毛片无码 | 学生妹亚洲一区二区 | 精品久久综合1区2区3区激情 | 国产熟女一区二区三区四区五区 | 欧美变态另类xxxx | 亚洲 a v无 码免 费 成 人 a v | 国内老熟妇对白xxxxhd | 一本无码人妻在中文字幕免费 | 97久久精品无码一区二区 | 亚洲中文字幕va福利 | 亚洲一区二区三区国产精华液 | 亚洲欧洲中文日韩av乱码 | 日本丰满护士爆乳xxxx | 图片区 小说区 区 亚洲五月 | 国产精品亚洲а∨无码播放麻豆 | 中文无码成人免费视频在线观看 | 精品国产一区二区三区四区在线看 | 国模大胆一区二区三区 | 日本精品人妻无码77777 天堂一区人妻无码 | 欧美人与善在线com | 午夜丰满少妇性开放视频 | 无遮挡啪啪摇乳动态图 | 亚洲国产精品久久人人爱 | 少妇高潮喷潮久久久影院 | 99久久久无码国产精品免费 | 无码人妻精品一区二区三区下载 | 水蜜桃av无码 | 中文精品久久久久人妻不卡 | 影音先锋中文字幕无码 | 亚洲精品一区二区三区婷婷月 | 97资源共享在线视频 | 久久久婷婷五月亚洲97号色 | 国产极品美女高潮无套在线观看 | 国产成人精品久久亚洲高清不卡 | 国产午夜亚洲精品不卡 | 国产成人精品视频ⅴa片软件竹菊 | 国产三级精品三级男人的天堂 | 亚洲欧美精品伊人久久 | 蜜臀av无码人妻精品 | а√天堂www在线天堂小说 | 精品久久久久久亚洲精品 | 久久久国产一区二区三区 | 亚洲日韩一区二区 | 久久久久久九九精品久 | 欧美老妇交乱视频在线观看 | 丰满诱人的人妻3 | 亚洲欧洲日本无在线码 | 一本精品99久久精品77 | 精品久久久久久人妻无码中文字幕 | 亚洲乱码日产精品bd | 亚洲综合精品香蕉久久网 | 亚洲s色大片在线观看 | www一区二区www免费 | 亚洲熟妇自偷自拍另类 | 疯狂三人交性欧美 | 久久综合狠狠综合久久综合88 | 午夜丰满少妇性开放视频 | 99久久99久久免费精品蜜桃 | 人妻中文无码久热丝袜 | 久久国产精品_国产精品 | 日韩视频 中文字幕 视频一区 | 初尝人妻少妇中文字幕 | 亚洲日韩av一区二区三区中文 | 无码国产激情在线观看 | 伊人久久婷婷五月综合97色 | 国产精品手机免费 | 中文字幕无码av激情不卡 | 国产午夜福利100集发布 | 欧洲欧美人成视频在线 | 网友自拍区视频精品 | 国产在热线精品视频 | 成在人线av无码免观看麻豆 | 亚洲热妇无码av在线播放 | 国产肉丝袜在线观看 | 伊人久久大香线蕉午夜 | 欧美35页视频在线观看 | 六月丁香婷婷色狠狠久久 | 久久综合色之久久综合 | 巨爆乳无码视频在线观看 | 内射爽无广熟女亚洲 | 97资源共享在线视频 | 欧洲极品少妇 | 精品国产一区二区三区四区 | 国产极品美女高潮无套在线观看 | 国产精品美女久久久久av爽李琼 | 亚洲精品中文字幕 | 国产特级毛片aaaaaaa高清 | 动漫av网站免费观看 | 国产一区二区三区日韩精品 | 亚洲中文字幕成人无码 | 成熟人妻av无码专区 | 国产97人人超碰caoprom | 六月丁香婷婷色狠狠久久 | 久久久精品人妻久久影视 | 久久精品中文字幕大胸 | 色欲久久久天天天综合网精品 | 午夜精品久久久内射近拍高清 | 在教室伦流澡到高潮hnp视频 | 日本高清一区免费中文视频 | 性欧美熟妇videofreesex | 久久综合九色综合欧美狠狠 | 亚洲小说春色综合另类 | 久久久国产精品无码免费专区 | 丁香花在线影院观看在线播放 | 精品国产一区二区三区四区 | 欧美人与善在线com | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 精品偷自拍另类在线观看 | 久久精品国产亚洲精品 | 日本一卡二卡不卡视频查询 | 亚洲成av人片天堂网无码】 | 亚洲第一无码av无码专区 | 欧美xxxx黑人又粗又长 | 玩弄中年熟妇正在播放 | 日韩人妻无码中文字幕视频 | 日本又色又爽又黄的a片18禁 | 天天综合网天天综合色 | 熟妇激情内射com | 久久视频在线观看精品 | 国产成人精品三级麻豆 | 青青青手机频在线观看 | 国内丰满熟女出轨videos | 国産精品久久久久久久 | 久久久久se色偷偷亚洲精品av | 免费无码av一区二区 | 乱码午夜-极国产极内射 | 国产精品人人爽人人做我的可爱 | 狠狠色丁香久久婷婷综合五月 | 又粗又大又硬毛片免费看 | 国产 精品 自在自线 | 亚洲aⅴ无码成人网站国产app | 久久国语露脸国产精品电影 | 人人爽人人澡人人高潮 | 4hu四虎永久在线观看 | 东京无码熟妇人妻av在线网址 | 蜜桃视频插满18在线观看 | 国产成人精品无码播放 | 午夜精品一区二区三区在线观看 | 无码人妻丰满熟妇区五十路百度 | 亚洲精品一区三区三区在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产成人无码av在线影院 | 午夜性刺激在线视频免费 | 波多野结衣av一区二区全免费观看 | 精品一区二区不卡无码av | 人妻互换免费中文字幕 | 国产熟妇高潮叫床视频播放 | 疯狂三人交性欧美 | 两性色午夜免费视频 | 国产97人人超碰caoprom | 成在人线av无码免观看麻豆 | 亚洲热妇无码av在线播放 | 亚洲第一无码av无码专区 | 精品无人区无码乱码毛片国产 | 亚洲中文字幕乱码av波多ji | 婷婷丁香六月激情综合啪 | 国产成人无码a区在线观看视频app | 日韩人妻无码中文字幕视频 | 久久久久久久女国产乱让韩 | 高清国产亚洲精品自在久久 | 亚洲人成影院在线观看 | 熟妇人妻无码xxx视频 | √天堂资源地址中文在线 | 成人女人看片免费视频放人 | 好爽又高潮了毛片免费下载 | 国产国产精品人在线视 | 大肉大捧一进一出好爽视频 | 丰满诱人的人妻3 | 亚洲 激情 小说 另类 欧美 | 亚洲综合伊人久久大杳蕉 | 国产99久久精品一区二区 | 99久久人妻精品免费一区 | 天堂а√在线中文在线 | 一二三四社区在线中文视频 | 国产精品第一区揄拍无码 | 亚洲色www成人永久网址 | 成人综合网亚洲伊人 | 国产人妻精品一区二区三区不卡 | 97无码免费人妻超级碰碰夜夜 | 国产成人精品一区二区在线小狼 | 伊人久久婷婷五月综合97色 | 狂野欧美性猛交免费视频 | 高潮喷水的毛片 | 风流少妇按摩来高潮 | 又粗又大又硬毛片免费看 | 国产熟女一区二区三区四区五区 | 国产成人一区二区三区在线观看 | 露脸叫床粗话东北少妇 | 亚洲色成人中文字幕网站 | 精品少妇爆乳无码av无码专区 | 又湿又紧又大又爽a视频国产 | 亚洲一区二区三区含羞草 | 福利一区二区三区视频在线观看 | 一本色道婷婷久久欧美 | 国产在线无码精品电影网 | 久久精品女人的天堂av | 动漫av一区二区在线观看 | 天天做天天爱天天爽综合网 | 扒开双腿吃奶呻吟做受视频 | 国产亚洲精品久久久ai换 | 九月婷婷人人澡人人添人人爽 | 亚洲国产精品久久久久久 | 久久精品99久久香蕉国产色戒 | 亚洲 a v无 码免 费 成 人 a v | 奇米影视7777久久精品人人爽 | 人妻少妇精品视频专区 | 中文字幕乱码人妻无码久久 | 理论片87福利理论电影 | 草草网站影院白丝内射 | 男女猛烈xx00免费视频试看 | 成人一在线视频日韩国产 | 少妇性俱乐部纵欲狂欢电影 | 久久99精品国产麻豆蜜芽 | 日本大香伊一区二区三区 | 嫩b人妻精品一区二区三区 | 性做久久久久久久久 | 狠狠噜狠狠狠狠丁香五月 | 国产av一区二区精品久久凹凸 | 人人妻人人澡人人爽人人精品浪潮 | 欧美亚洲国产一区二区三区 | 久久婷婷五月综合色国产香蕉 | 久久99国产综合精品 | aa片在线观看视频在线播放 | 亚洲 激情 小说 另类 欧美 | 中文字幕人妻无码一夲道 | аⅴ资源天堂资源库在线 | www国产精品内射老师 | 亚洲 日韩 欧美 成人 在线观看 | 俺去俺来也www色官网 | 熟妇人妻无乱码中文字幕 | 久久久久亚洲精品中文字幕 | 亚洲精品综合五月久久小说 | 国产成人无码午夜视频在线观看 | 久久久婷婷五月亚洲97号色 | yw尤物av无码国产在线观看 | 99久久精品午夜一区二区 | 国产 精品 自在自线 | 国产成人综合美国十次 | 国内精品久久毛片一区二区 | 亚洲一区二区观看播放 | 中文字幕人妻无码一夲道 | 精品国产一区二区三区四区 | 内射巨臀欧美在线视频 | 久久精品中文字幕大胸 | 国产小呦泬泬99精品 | 亚洲国产精品一区二区美利坚 | 丰满诱人的人妻3 | 久久综合香蕉国产蜜臀av | 狂野欧美性猛交免费视频 | 99久久久无码国产aaa精品 | 窝窝午夜理论片影院 | 亚洲国产日韩a在线播放 | 一本色道婷婷久久欧美 | 无码人妻久久一区二区三区不卡 | 久久国产精品_国产精品 | 在线播放无码字幕亚洲 | 亚洲精品无码国产 | 国产乱码精品一品二品 | 99精品无人区乱码1区2区3区 | 国产av剧情md精品麻豆 | 无码人妻丰满熟妇区五十路百度 | 鲁鲁鲁爽爽爽在线视频观看 | 永久免费观看美女裸体的网站 | 国产av无码专区亚洲a∨毛片 | 亚洲区小说区激情区图片区 | 黑森林福利视频导航 | 在线视频网站www色 | 少妇无码吹潮 | 狠狠综合久久久久综合网 | 亚洲中文字幕无码中文字在线 | 免费看男女做好爽好硬视频 | 初尝人妻少妇中文字幕 | 自拍偷自拍亚洲精品被多人伦好爽 | 狠狠色丁香久久婷婷综合五月 | 久久视频在线观看精品 | 亚洲中文字幕无码中字 | 亚洲热妇无码av在线播放 | 99久久亚洲精品无码毛片 | 成年美女黄网站色大免费全看 | 久久精品一区二区三区四区 | 久久99精品国产麻豆 | 精品一区二区三区波多野结衣 | 国产精品鲁鲁鲁 | 国产午夜无码视频在线观看 | 天堂一区人妻无码 | 国产精品内射视频免费 | 国产在线无码精品电影网 | 欧美日本日韩 | 久久天天躁夜夜躁狠狠 | 男人的天堂av网站 | av无码电影一区二区三区 | 国产亚洲精品久久久久久久久动漫 | 国产乱码精品一品二品 | 国产精品无码一区二区三区不卡 | 亚洲色在线无码国产精品不卡 | 三级4级全黄60分钟 | 无码一区二区三区在线 | 日本熟妇大屁股人妻 | 国产艳妇av在线观看果冻传媒 | 亚洲色欲色欲欲www在线 | 成人免费无码大片a毛片 | 久久人人爽人人爽人人片av高清 | 欧美肥老太牲交大战 | 亚洲欧美综合区丁香五月小说 | 国产一区二区三区四区五区加勒比 | 国产精品美女久久久网av | 国产69精品久久久久app下载 | 天天综合网天天综合色 | 国产真实伦对白全集 | 国内精品九九久久久精品 | 中文字幕乱码人妻二区三区 | 又大又黄又粗又爽的免费视频 | 日本精品久久久久中文字幕 | 亚洲欧美精品aaaaaa片 | a国产一区二区免费入口 | 国产成人人人97超碰超爽8 | 性生交大片免费看女人按摩摩 | 国产精品无码一区二区桃花视频 | 色一情一乱一伦一区二区三欧美 | 久久精品女人天堂av免费观看 | 久久99精品国产麻豆蜜芽 | 妺妺窝人体色www在线小说 | 妺妺窝人体色www在线小说 | 蜜臀av无码人妻精品 | 欧美丰满熟妇xxxx | 少妇厨房愉情理9仑片视频 | 日本在线高清不卡免费播放 | 在线a亚洲视频播放在线观看 | 久久亚洲国产成人精品性色 | 国产99久久精品一区二区 | 亚洲精品国产精品乱码视色 | 久久www免费人成人片 | 中文亚洲成a人片在线观看 | 国产成人午夜福利在线播放 | 国产亚洲人成a在线v网站 | 国产莉萝无码av在线播放 | 青草青草久热国产精品 | 欧美人与物videos另类 | 丰满妇女强制高潮18xxxx | 精品成人av一区二区三区 | 波多野结衣高清一区二区三区 | 久久久久成人精品免费播放动漫 | 亚洲成av人在线观看网址 | 亚洲日韩一区二区 | 国产av久久久久精东av | 国产成人综合在线女婷五月99播放 | 荫蒂添的好舒服视频囗交 | 四虎影视成人永久免费观看视频 | 久久亚洲a片com人成 | 丰满人妻精品国产99aⅴ | 色爱情人网站 | 又紧又大又爽精品一区二区 | 在线а√天堂中文官网 | 2020久久超碰国产精品最新 | 高清国产亚洲精品自在久久 | 男女爱爱好爽视频免费看 | 无遮无挡爽爽免费视频 | 中文字幕无码免费久久99 | 3d动漫精品啪啪一区二区中 | 午夜男女很黄的视频 | 在线观看国产一区二区三区 | 领导边摸边吃奶边做爽在线观看 | 黑人巨大精品欧美黑寡妇 | 思思久久99热只有频精品66 | 少妇人妻偷人精品无码视频 | 亚洲男人av天堂午夜在 | 国产无遮挡又黄又爽又色 | 午夜精品一区二区三区的区别 | 亚洲国产精品毛片av不卡在线 | 激情爆乳一区二区三区 | 色五月丁香五月综合五月 | 男人的天堂2018无码 | 小泽玛莉亚一区二区视频在线 | 在线播放免费人成毛片乱码 |