日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring MVC源码解析

發(fā)布時(shí)間:2025/3/21 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC源码解析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Spring Mvc結(jié)構(gòu)解析

上圖是Dispatcher Servlet的結(jié)構(gòu)圖,從圖中可以清楚的看到Dispatcher Servlet的繼承鏈,下面我們將基于Spring4.1.6揭開(kāi)Spring MVC的神秘面紗。

初始化過(guò)程

我們都知道,Java中初始化順序是:

  • 初始化父類靜態(tài)變量(靜態(tài)代碼塊,靜態(tài)變量,靜態(tài)方法,需要注意的是main方法也是靜態(tài)的)
  • 初始化子類靜態(tài)變量(范圍同父類)
  • 初始化父類普通成員變量及方法
  • 調(diào)用父類構(gòu)造方法
  • 初始化子類普通成員變量及方法
  • 調(diào)用子類構(gòu)造方法
  • 那么,在Dispatcher Servlet初始化的時(shí)候也是嚴(yán)格按照這個(gè)順序來(lái)執(zhí)行的。我們分別來(lái)看看在不同階段都做了些什么。

    HttpServletBean初始化過(guò)程關(guān)鍵代碼

    @Overridepublic final void init() throws ServletException {// 從spring的配置文件中讀取servlet的Init-Param。即spring配置文件路徑等關(guān)鍵配置try {PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));initBeanWrapper(bw);bw.setPropertyValues(pvs, true);}catch (BeansException ex) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);throw ex;}// 調(diào)用frameworkServlet的方法初始化initServletBean();}

    FrameworkServlet初始化過(guò)程關(guān)鍵代碼

    @Overrideprotected final void initServletBean() throws ServletException { this.webApplicationContext = initWebApplicationContext(); }protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (wac == null) {// 在這里初始化Spring MVC的context,并將Spring MVC的context和Servlet Context綁定wac = createWebApplicationContext(rootContext);}return wac;}protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {Class<?> contextClass = getContextClass();// 通過(guò)反射new一個(gè)空的context對(duì)象返回ConfigurableWebApplicationContext wac =(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());wac.setParent(parent);wac.setConfigLocation(getContextConfigLocation());// 在這里會(huì)調(diào)用onRefreah方法,初始化Dispatcher Servlet的9大策略configureAndRefreshWebApplicationContext(wac);return wac;}protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {if (ObjectUtils.identityToString(wac).equals(wac.getId())) {// The application context id is still set to its original default value// -> assign a more useful id based on available informationif (this.contextId != null) {wac.setId(this.contextId);}else {wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +ObjectUtils.getDisplayString(getServletContext().getContextPath()) + "/" + getServletName());}}// 為web application context設(shè)置基本屬性wac.setServletContext(getServletContext());wac.setServletConfig(getServletConfig());wac.setNamespace(getNamespace());wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));ConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());}postProcessWebApplicationContext(wac);applyInitializers(wac);// 關(guān)鍵,這里會(huì)刷新整個(gè)context,調(diào)用Dispatcher Servlet的onRefreah方法。初始化一系列Resolverswac.refresh();}

    DispatcherServlet初始化過(guò)程關(guān)鍵代碼

    /*** This implementation calls {@link #initStrategies}.*/@Overrideprotected void onRefresh(ApplicationContext context) {initStrategies(context);}/*** Initialize the strategy objects that this servlet uses.* <p>May be overridden in subclasses in order to initialize further strategy objects.*/protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);// 尋找配置的HandlerMapping,下篇文章我們會(huì)繼續(xù)分析這里的詳細(xì)過(guò)程。是url映射controller的關(guān)鍵,默認(rèn)是RequestMappgingHandlerMapping和BeanNameUrlHandlerMapping,這些HandlerMapping會(huì)在spring context初始化的時(shí)候初始化。initHandlerMappings(context);// 尋找配置的適配器,默認(rèn)是RequestMappingHandlerAdapter,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter這三種initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}

    從上面的關(guān)鍵部分代碼可以看出Spring MVC在啟動(dòng)時(shí)的的大概流程,大致了解Spring MVC都做了什么。后續(xù)會(huì)繼續(xù)分析請(qǐng)求到達(dá)Dispatcher Servlet后是如何找到對(duì)應(yīng)的controller以及參數(shù)封裝,最后再到數(shù)據(jù)返回等流程的詳細(xì)過(guò)程。

    總結(jié)

    以上是生活随笔為你收集整理的Spring MVC源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。