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

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring MVC 实现原理

發布時間:2025/7/14 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC 实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring*.xml</param-value> </context-param> <listener><listener>org.springframework.web.context.ContextLoaderListener</listener> </listener><servlet><servlet-name>test</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath*:config/test-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup> </servlet> <servlet-mapping><servlet-name>test</servlet-name><url-pattern>/</url-pattern> </servlet-mapping>

從這個配置里面看見,一個配置上下文的監聽器,這個監聽器負責整個 IOC 容器 在 Web 環境中的啟動工作,另外一個是配置 SpringMVC 的分發請求器。他們共同構成了 Spring 和 Web 容器的接口操作,他們與 Web容器的 耦合 是通過ServletContext 初始化的,而DispatcherServlet就負責 Web 請求轉發的建立,完成 http 的請求響應。

?

在這個啟動過程中可以看見系統加載是依賴 web 容器的 ?ServletContextListener 來觸發的,這個Listener的觸發會在如下時候:

當 Servlet 容器啟動或終止 Web應用時,會觸發 ServletContextEvent 事件,該事件由ServletContextListener 來處理。在 ServletContextListener 接口定義了處理 ServletContextEvent 事件的兩個方法。

  • contextInitialized( ServletContextEvent sce): 當 Servlet容器啟動Web應用的時,調用該方法;調用完成之后,容器在對 Filter 初始化,并且對那些在 Web應用啟動時就需要被初始化的 Servlet 進行初始化。
  • contextDestroyed( ServletContextEvent sce) : 當Servlet容器終止 Web應用時候調用該方法;在調用該方法之前,容器會銷毀所有的 Servlet 和 Filter。
  • 在 Spring 會在 Web容器啟動的過程中,借助這個監聽器來創建它的上下文,而這個上下文其實就是 IOC 容器的初始化過程。而這個上下文初始化的過程同時也會把這個 ServletContext 給設置上,以供后面的 WebApplicationContext 來獲取 Web容器級別的全局屬性。

    先看下這個創建的 XmlWebApplicationContext 上下文的類繼承關系:

    ?

    它的 refresh 過程其實是在 AbstractApplicationContext 完成的,如下代碼:

    @Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}

    這個就是之前 spring ioc 中已經講到過的容器啟動過程,在 XmlWebApplicationContext它重寫了 beanDefinition 的加載,如下代碼

    /*** Loads the bean definitions via an XmlBeanDefinitionReader.* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader* @see #initBeanDefinitionReader* @see #loadBeanDefinitions*/@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}

    對于這個實現類它主要添加了對 web 環境 和 xml配置類的定義處理,例如:

    /** Default config location for the root context */public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";/** Default prefix for building a config location for a namespace */public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";/** Default suffix for building a config location for a namespace */public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

    這三個靜態的定義就是專門為 web 環境來設置的,相對于配置資源的獲取從以下這段重寫的代碼可以看出:

    /*** The default location for the root context is "/WEB-INF/applicationContext.xml",* and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"* (like for a DispatcherServlet instance with the servlet-name "test").*/@Overrideprotected String[] getDefaultConfigLocations() {if (getNamespace() != null) {return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};}else {return new String[] {DEFAULT_CONFIG_LOCATION};}}

    在 啟動時序中 有一個 initWebApplicationContext 的過程,這個過程里面有如下一段代碼可以簡單的說明一下:

    if(this.context == null){this.context = createWebApplicationContext(servletContext); }

    也就是 context 創建過程,這個 createWebApplcationContext 的如下實現:

    protected WebApplicationContext createWebApplicationContext(ServletContext sc) {Class<?> contextClass = determineContextClass(sc);if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Custom context class [" + contextClass.getName() +"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");}return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);}

    在創建 WebApplicationContext 的時候這里面有一個選擇上下文 class 的方法:

    protected Class<?> determineContextClass(ServletContext servletContext) {String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);if (contextClassName != null) {try {return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load custom context class [" + contextClassName + "]", ex);}}else {contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());try {return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load default context class [" + contextClassName + "]", ex);}}}

    首先會判斷在 web 容器的上下文全局屬性里面沒有做設置,如果做了設置就使用這個類。如果沒有設置就從一個默認的策略 properties 里面去獲取這個配置,這個配置的默認文件內容如下:

    # Default WebApplicationContext implementation class for ContextLoader. # Used as fallback when no explicit context implementation has been specified as context-param. # Not meant to be customized by application developers. org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

    也就是說 spring 的 MVC 默認上下文就是 XmlApplicationContext ,驗證了對這個類的分析。

    轉載于:https://my.oschina.net/exit/blog/812688

    總結

    以上是生活随笔為你收集整理的Spring MVC 实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 亚洲一线av | 久久久精品人妻一区二区三区四 | 日韩福利在线观看 | 爱涩av| 日韩亚洲欧美综合 | 高潮毛片无遮挡免费看 | 亚洲AV成人无码电影在线观看 | 操www | 久久久久久久久久久久久久久久久 | 国产日韩免费 | 精品一区二区三区免费看 | 国产美女一区二区 | 欧美日韩一区二区中文字幕 | 午夜777 | 色婷婷久久久亚洲一区二区三区 | 五月天小说网 | 四虎视频国产精品免费入口 | 欧美伊人网 | 在线免费毛片 | 天天干天天日夜夜操 | 黄色污污网站在线观看 | 最近日本中文字幕 | 337p日本大胆噜噜噜鲁 | 无码人妻精品一区二区三区99不卡 | 美日韩丰满少妇在线观看 | 中文字幕无码乱人伦 | 国产精品96久久久久久 | 日本老年老熟无码 | 日日碰狠狠添天天爽无码av | 天堂在线一区二区 | 9.1成人看片 | 国模无码一区二区三区 | 欧美a级黄色 | 国产在线视频自拍 | 久久精品亚洲精品国产欧美 | 丁香婷婷社区 | 91美女网 | 一区二区三区四区中文字幕 | 欧美精品首页 | 国产九色在线播放九色 | 嫩草影院懂你的影院 | 尤物193.com | 日韩国产三级 | 99热这里只有精品4 精品国产黄色 | 日韩av在线影院 | 波多野结衣一区二区三区 | 直接看的毛片 | 六月色婷婷 | 两口子交换真实刺激高潮 | 精品人妻无码一区二区三区换脸 | 精品xxx| 国产一区二区三区91 | 欧美有码在线 | 一本色道久久综合精品婷婷 | 成人久久视频 | 激情五月婷婷色 | 欧美日韩专区 | 午夜18视频在线观看 | 极品美女销魂一区二区三区 | 亚洲亚洲人成综合网络 | 亚欧中文字幕 | 可以在线观看的av | 亚洲综合色在线观看 | 日韩成人小视频 | 久久白浆| 老妇裸体性猛交视频 | 国产91综合 | 超碰操| 福利电影一区二区 | 福利一区福利二区 | 精久久 | 中文字幕在线视频一区 | 亚洲AV无码阿娇国产精品 | 色欲AV无码精品一区二区久久 | 日本成人在线网站 | 欧美丰满一区二区免费视频 | 五月天婷婷丁香花 | 黑人糟蹋人妻hd中文字幕 | 亚洲最新av网址 | 免费看91的网站 | 亚洲偷偷 | 色狠狠一区二区 | 日韩在线观看视频一区二区三区 | 熟妇高潮喷沈阳45熟妇高潮喷 | 国产原创在线观看 | 天天射天天草 | 无码国模国产在线观看 | 久久综合鬼色 | 男生和女生一起差差差视频 | 亚洲高h| 特级特黄刘亦菲aaa级 | 国模丫头1000人体 | 国产精品第十页 | 免费久久久久久 | 国产伦精品一区二区三区精品 | 中文字幕精品一二三四五六七八 | 亚洲精品久久久久av无码 | 亚洲天堂手机 | 国产午夜在线播放 |