深入浅出学习Struts框架(八):分析Struts框架实例3
? ? ? 上篇博客介紹了在ActionServlet的init方法實例化的時候完成的三個方法,主要是介紹了initInternal()方法、initOther()方法、initServlet()方法這三個方法。
? ? ? ?通過上篇博客的介紹我門知道initInternal()方法主要是創建資源類MessageResources的,比如說國際化資源等,具體這里可以見org.apache.struts.action下的ActionResources.properties文件;initOther()方法初始化其它的配置,獲取我們自己的struts-config配置文件的路徑,而它的默認路徑就是web-inf/struts-config.xml,另外這個方法還會注冊一些轉換類的;而initServlet()方法就是主要利用digester來解析web.xml下的配置內容。
? ? ? ?今天將繼續講解init方法中做的其他的事情。首先說在說之前還是先講init方法的具體實現代碼寫出來以便大家方便閱讀和理解。
? ? ? ?Init源代碼:
public void init() throws ServletException { try { //初始化資源類 initInternal(); //注冊轉換類 initOther(); //利用digester讀取web.xml文件并且將其放到servletContext中 initServlet(); getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this); initModuleConfigFactory(); ModuleConfig moduleConfig = initModuleConfig("", config); initModuleMessageResources(moduleConfig); initModuleDataSources(moduleConfig); initModulePlugIns(moduleConfig); moduleConfig.freeze(); Enumeration names = getServletConfig().getInitParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); if (!name.startsWith("config/")) { continue; } String prefix = name.substring(6); moduleConfig = initModuleConfig (prefix, getServletConfig().getInitParameter(name)); initModuleMessageResources(moduleConfig); initModuleDataSources(moduleConfig); initModulePlugIns(moduleConfig); moduleConfig.freeze(); } this.initModulePrefixes(this.getServletContext()); this.destroyConfigDigester(); } catch (UnavailableException ex) { throw ex; } catch (Throwable t) { log.error("Unable to initialize Struts ActionServlet due to an " + "unexpected exception or error thrown, so marking the " + "servlet as unavailable. Most likely, this is due to an " + "incorrect or missing library dependency.", t); throw new UnavailableException(t.getMessage()); } }
? ? ? ? getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY,this);這句話是將ActionServlet實例將以Globals.ACTION_SERVLET_KEY作為key存入servletcontext中。
? ? ? ?這里的Globals.ACTION_SERVLET_KEY在ActionServlet已經給出了聲明:
public static final String ACTION_SERVLET_KEY= "org.apache.struts.action.ACTION_SERVLET";
? ? ? ? 接下來initModuleConfigFactory()方法,這個方法主要的作用是解析在web.xml中configFactory的text值。如果configFactory有配置,則將設置ModuleConfigFactory中得factoryClass值,否則默認得為 ? ? ? ? ? ? ? DefaultModuleConfigFactory。該方法其實宗旨是讓開發人員自己開發出ModuleConfigFactory,從而得到自己所需要的ModuleConfig類。因為我們的實例中沒有配置這個參數信息,所以我們這里的實例是要defalutModelConfigFactory了。
? ? ? 代碼段一:
protected voidinitModuleConfigFactory(){ String configFactory =getServletConfig().getInitParameter("configFactory"); if (configFactory != null) { ModuleConfigFactory.setFactoryClass(configFactory); } }
? ? ? 代碼段二:
public static void setFactoryClass(String factoryClass) { ModuleConfigFactory.factoryClass = factoryClass; ModuleConfigFactory.clazz = null; }
? ? ?代碼段三:
protected static String factoryClass = "org.apache.struts.config.impl.DefaultModuleConfigFactory"; }
? ? ? ModuleConfig moduleConfig =initModuleConfig("", config)方法是非常重要的,initModuleConfig方法給strits-config里面的屬性初始化后放入moduleConfig對象里面去,放到moduleConfig對象里面去便于以后操作更快,因為它是文件流。
? ? ?具體實現代碼:
protected ModuleConfig initModuleConfig(Stringprefix, String paths) throws ServletException { // :FIXME: Document UnavailableException? (Doesn't actually throw anything) if (log.isDebugEnabled()) { log.debug( "Initializing module path '" + prefix + "' configuration from '" + paths + "'"); } // Parse the configuration for this module ModuleConfigFactory factoryObject= ModuleConfigFactory.createFactory(); ModuleConfig config =factoryObject.createModuleConfig(prefix); // Configure the Digester instance we will use Digester digester =initConfigDigester(); // Process each specified resource path while (paths.length() > 0) { digester.push(config); String path = null; int comma = paths.indexOf(','); if (comma >= 0) { path =paths.substring(0, comma).trim(); paths =paths.substring(comma + 1); } else { path = paths.trim(); paths = ""; } if (path.length() < 1){ break; } this.parseModuleConfigFile(digester,path); } getServletContext().setAttribute( Globals.MODULE_KEY +config.getPrefix(), config); // Force creation and registration of DynaActionFormClass instances // for all dynamic form beans we wil be using FormBeanConfig fbs[] =config.findFormBeanConfigs(); for (int i = 0; i < fbs.length; i++) { if (fbs[i].getDynamic()) { fbs[i].getDynaActionFormClass(); } } return config; }
? ? ? ?這里有必要解析一下這段代碼。首先得到繼承ModuleConfigFactory的實現類,如果在initModuleConfigFactory()中能設置factoryClass屬性,則能生成客戶化得factory,否則得到得是默認得DefaultModuleConfigFactory類,該工廠得到ModuleConfigImpl類。然后調用initConfigDigester()該方法為解析配置文件做準備,初始化Digest類(具體digest的初始化實現就不講解)。最后返回ModuleConfig,而這時的ModuleConfig里面封裝了所有的struts-config.xml中的信息。
? ? ? 最后的幾個方法就簡單說一下就行,不是非常難理解:
? ? ? initModuleMessageResources(moduleConfig)方法是通過moduleConfig中的配置文件信息,創建MessageResource對象.
? ? ? initModuleDataSources(moduleConfig)方法是通過moduleConfig中的配置文件信息,創建DataSource對象.?? initModulePlugIns(moduleConfig)加載并初始化默認應用模塊的所有插件的。
? ? ? moduleConfig.freeze()是將配置文件中的各個對象,設置成已配置狀態.
? ? ?最后我們看到了,下面還有一段同上面代碼的循環代碼,這段代碼的主要意思就是當默認子應用模塊被成功初始化后,如果應用還包括其他子應用模塊,將重復流程,分別對其他子應用模塊進行初始化。這個也是很好理解的。
? ? ?到此為止ActionServlet就init完成。
?
? ? ? 經過這兩篇博客的源碼分析,我們能夠很清晰的知道在為什么在web.xml文件下會那樣配置信息,也知道程序是怎么樣初始化ActionServlet的了。下一篇博客講ActionServlet是如何截取字符串的。敬請關注
?
?
轉載于:https://www.cnblogs.com/springmvc-hibernate/archive/2012/04/06/2483896.html
總結
以上是生活随笔為你收集整理的深入浅出学习Struts框架(八):分析Struts框架实例3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用户体验——减少用户的操作!
- 下一篇: CDOJ1633 Video Game