<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    牙牙窩

    BlogJava 聯(lián)系 聚合 管理
      8 Posts :: 21 Stories :: 10 Comments :: 0 Trackbacks

    ?

    一、??????? 概述

    Spring MVC 的開發(fā)是基于 action-servlet.xml 進(jìn)行配置,但不支持開發(fā)模式下進(jìn)行動態(tài)的配置文件載入。本文主要是介紹如何修改 Spring 的源代碼,使 Spring 支持動態(tài)的配置文件更新,讓開發(fā)變得更加簡單。

    二、??????? 實現(xiàn) action-servlet.xml 動態(tài)載入

    ??? Spring 提取配置文件的思路 :每次 Spring MVC 會在使用前將 XML 文件載入內(nèi)存中,并生成映射類的實例,放在 Mapping Map 里。然后判斷每個請求,如果有其 URL 所對應(yīng)的映射,則返回其對應(yīng)的 Action 實例。

    ??? 修改思路 :將每次得到請求時,讓程序重新載入 xml 文件,并實例化其映射,然后放入 Mapping Map 中。

    1、???????????? 首先是 FrameworkServlet ,他是 DispatcherServlet 的基類。 XML 在載入內(nèi)存后,放在一個叫 WebApplicationContext 的類中。找到 getWebApplicationContext() 方法,加入以下代碼:

    ?????? ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils

    ????????????? .instantiateClass(getContextClass());

    ?????? wac.setParent(WebApplicationContextUtils

    ????????????? .getWebApplicationContext(getServletContext()));

    ?????? wac.setServletContext(getServletContext());

    ?????? wac.setNamespace(getNamespace());

    ?????? if (getContextConfigLocation() != null ) {

    ?????????? wac

    ????????????????? .setConfigLocations(StringUtils

    ???????????????????????? .tokenizeToStringArray(

    ??????????????????????????????? getContextConfigLocation(),

    ??????????????????????????? ??? ConfigurableWebApplicationContext. CONFIG_LOCATION_DELIMITERS ));

    ?????? }

    ?????? wac.refresh();

    ?????? this . webApplicationContext = wac;

    這樣每次再讀取 WebApplicationContext 的時候,會重新載入 XML 文件一次。

    ?

    2、???????????? 修改 DispatcherServlet ,這個 Servlet 是處理所有請求的入口。找到 getHandler() 這個方法,他負(fù)責(zé)找到相應(yīng)的 Action ,并返回其實例。將代碼中的

    ?????? Iterator it = this.handlerMappings.iterator();

    ?????? while (it.hasNext()) {

    ?????????? HandlerMapping hm = (HandlerMapping) it.next();

    ?????????? if (logger.isDebugEnabled()) {

    ????????????? logger.debug("Testing handler map [" + hm? + "] in DispatcherServlet with name '" +

    ???????????????????? getServletName() + "'");

    ?????????? }

    ?????????? handler = hm.getHandler(request);

    ?????????? if (handler != null) {

    ????????????? if (cache) {

    ????????????????? request.setAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE, handler);

    ????????????? }

    ????????????? return handler;

    ?????????? }

    ?????? }

    改為

    ?????? initHandlerMappings();

    ??????

    ?????? Iterator it = this . handlerMappings .iterator();

    ?????? while (it.hasNext()) {

    ?????????? BeanNameUrlHandlerMapping hm = (BeanNameUrlHandlerMapping) it.next();

    ?????????? if ( logger .isDebugEnabled()) {

    ????????????? logger .debug( "Testing handler map [" + hm? + "] in DispatcherServlet with name '" +

    ???????????????????? getServletName() + "'" );

    ?????????? }

    ?????????? hm.initApplicationContext();

    ?????????? handler = hm.getHandler(request);

    ?????????? if (handler != null ) {

    ????????????? if (cache) {

    ????????????????? request.setAttribute( HANDLER_EXECUTION_CHAIN_ATTRIBUTE , handler);

    ????????????? }

    ????????????? return handler;

    ?????????? }

    ?????? }

    注解:

    1)?? 其中 BeanNameUrlHandlerMapping 是將強制轉(zhuǎn)換 HandlerMapping 時,用子類代替父類,因為子類提供了一個重新初始化的方法 initApplicationContext() ,調(diào)用該方法可以重新載入 WebApplicationContext , 并刷新 Mapping Map

    2)?????? initHandlerMappings() DispatcherServlet 初始化 Mapping 的一個方法。在生成 WebApplicationContext 時,程序還會把放在 ApplicationObjectSupport.applicationContext 保存,因此需要重新初始化一次。

    ?

    3 、修改 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping

    類中的 registerHandler() 方法,它的作用是注冊 Mapping ,去掉重復(fù)性校驗,將下面幾行代碼注釋掉。

    ??? if (mappedHandler != null) {

    ??????? throw new ApplicationContextException(

    ?????????????? "Cannot map handler [" + handler + "] to URL path [" + urlPath +

    ?????????????? "]: there's already handler [" + mappedHandler + "] mapped");

    ??? }

    ?

    ?

    三、實現(xiàn) applicationContext.xml 的動態(tài)載入

    ??? Spring 實現(xiàn)思路: applicationContext.xml Spring 默認(rèn)的配置文件,它利用配置 ContextLoaderListener 的方式,在應(yīng)用載入時啟動,并將 applicationContext.xml 載入內(nèi)存中,放在 ServletContext Attribute 中,保存的方式是一個 WebApplicationContext 類。當(dāng)每次調(diào)用類時, beanFactory 會調(diào)用 WebApplicationContextUtils 中的方法 getWebApplicationContext() ,得到配置信息。

    ??? 修改方法: ContextLoaderListener 初始化 WebApplicationContext 時,會利用 ContextLoader 提供的方法 initWebApplicationContext() 進(jìn)行初始化,我們只需要得到 Listener 的這個 ContextLoader 的實例,并重新調(diào)用一個初始化的方法就可以實現(xiàn)重新載入了。

    ??? 修改步驟:

    1 、找到 ContextLoaderListener 類的方法 contextInitialized() ,在 Context 初始化的時候?qū)?/span> ContextLoader 的引用放在 ServletContext Attribute 中:

    public void contextInitialized(ServletContextEvent event) {

    ?????? this . contextLoader = createContextLoader();

    ?????? this . contextLoader .initWebApplicationContext(event.getServletContext());

    ?????? event.getServletContext().setAttribute( "ListenerContextLoader" , this . contextLoader );

    }

    注: "ListenerContextLoader" 是自定義的名稱,可以任意修改。

    ?

    3、???????????? 找到 WebApplicationContextUtils 類的方法 getWebApplicationContext() ,修改第一行代碼:

    Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

    改為:

    ?????? Object attr = null ;

    ?????? ContextLoader cl = (ContextLoader) sc

    ????????????? .getAttribute( "ListenerContextLoader" );

    ?????? if (cl != null )

    ?????????? attr = cl.initWebApplicationContext(sc);

    這樣,在每次獲取 WebApplicationContext 時,程序會重新載入 applicationContext.xml 一次。

    ?

    OK !大功告成, Enjoy your spring developing !!!

    ?

    posted on 2006-12-06 09:38 大牙 閱讀(9669) 評論(7)  編輯  收藏 所屬分類: 架構(gòu)師歷程

    Feedback

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2007-11-19 14:38 tedeyang
    good,樓主很能鉆。
    不過用監(jiān)視xml文件的方式更好一點,否則刷新得太頻繁了。  回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2007-11-19 14:38 tedeyang
    另外在bean依賴關(guān)系復(fù)雜的時候會比較麻煩。  回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2008-03-27 11:25 疑問
    我修改了怎么不成功呢?   回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2009-07-09 11:12 hezhuo1985
    @tedeyang
    監(jiān)視xml文件是怎樣實現(xiàn)的?
      回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2009-07-09 11:50 hezhuo1985
    實現(xiàn) applicationContext.xml 的動態(tài)載入 ,具體怎么操作?
      回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2011-12-08 10:48 陳華
    請問樓主。如何不修改源碼實現(xiàn)這樣的需求:

    在服務(wù)器運行的狀態(tài),修改Spring中的數(shù)據(jù)庫連接,讓它重新加載。萬分感謝!

    QQ 705541917

    chengongmo@126.com  回復(fù)  更多評論
      

    # re: 關(guān)于Spring配置文件的動態(tài)載入的修改 2012-02-15 15:20 jakey766
    每次進(jìn)入DispatcherServlet 時重新加載一下不太合理呀,LZ現(xiàn)在有其他方法沒?spring中的那幾個方法都用final修飾了,想改都改不了啊  回復(fù)  更多評論
      

    主站蜘蛛池模板: 美女被免费网站视频在线| 老司机亚洲精品影院无码| 免费一级毛片清高播放| 国产精品jizz在线观看免费| 成人性生免费视频| 国产卡一卡二卡三免费入口| 在线精品一卡乱码免费| 亚洲三级高清免费| 最近的免费中文字幕视频| 成人免费无码大片a毛片软件| 成人看的午夜免费毛片| 日韩在线免费播放| 亚洲不卡无码av中文字幕| 亚洲第一页综合图片自拍| 亚洲日韩在线第一页| 亚洲日韩精品一区二区三区| 亚洲国产精品无码久久一区二区 | 黄网站免费在线观看| 国产99视频精品免费专区| 18女人毛片水真多免费| 99久久99这里只有免费费精品| 久久精品a一国产成人免费网站| 在线观看免费毛片| 亚洲国产精品嫩草影院久久| 亚洲精品无码久久久久去q| 久久久久亚洲av无码专区| 亚洲一线产区二线产区精华| 亚洲精品蜜夜内射| 五月天婷婷精品免费视频| 毛片免费在线观看| 91网站免费观看| 国产一区二区三区在线免费观看| 久久久久久久亚洲精品| 亚洲高清在线视频| 亚洲最大的成人网站| 一级毛片**免费看试看20分钟| 免费无码中文字幕A级毛片| 国产成人免费爽爽爽视频| 四虎精品亚洲一区二区三区| 亚洲级αV无码毛片久久精品| 亚洲自偷自拍另类图片二区|