注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

我的博客

等闲识得东风面,万紫千红总是春!

 
 
 

日志

 
 

Struts的资源文件是如何初始化的--struts源码学习  

2008-11-29 16:06:48|  分类: struts2 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

    // 取得当前的配置文件   

InputStream input =

            getServletContext().getResourceAsStream("/WEB-INF/web.xml");

 

        if (input == null) {

            log.error(internal.getMessage("configWebXml"));

            throw new ServletException(internal.getMessage("configWebXml"));

        }

 

        try {

            // 解析当前配置文件

digester.parse(input);

 

        } catch (IOException e) {

            log.error(internal.getMessage("configWebXml"), e);

            throw new ServletException(e);

 

        } catch (SAXException e) {

            log.error(internal.getMessage("configWebXml"), e);

            throw new ServletException(e);

 

        } finally {

            try {

                // 解析完毕,关闭输入

input.close();

            } catch (IOException e) {

                log.error(internal.getMessage("configWebXml"), e);

    /**           

如果有异常,当前部进行处理,而是留给他的调用者来处理。其实是当前的调用部分没有处理的能力。我们可以这样理解,假设你想在出现了这类异常异常的地方给用户一个提示,但是在我们封装功能实现的时候,我们并不知道谁会来调用,所以我们只有把异常抛出,让调用者自己去处理。

    这一点也许不太好理解,不过,如果理解了,可能你就能够灵活的使用异常了。

*/

throw new ServletException(e);

            }

        }

 

        // Record a servlet context attribute (if appropriate)

        if (log.isDebugEnabled()) {

            log.debug("Mapping for servlet '" + servletName + "' = '" +

                servletMapping + "'");

        }

 

        if (servletMapping != null) {

            getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);

        }

 

    }

[7] 初始化其他模块

(1)   初始化工厂

            getServletContext().setAttribute( Globals . ACTION_SERVLET_KEY , this );

            initModuleConfigFactory();

(2)   初始化资源模块

            // Initialize modules as needed

            ModuleConfig moduleConfig = initModuleConfig( "" , config );

             initModuleMessageResources(moduleConfig);

(3)   初始化数据源配置模块

            initModuleDataSources(moduleConfig);

(4)   初始化 PlugIn 模块

            initModulePlugIns(moduleConfig);

            moduleConfig.freeze();

[8]   初始化参数

            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();

            }

[9]   我也不知道做什么用的    

            this .initModulePrefixes( this .getServletContext());

   

            this .destroyConfigDigester();

以上就是Struts的初始化流程。

[10]          部分模块的详细实现:

a.       工厂的初始化如何实现的:

    /**

     * <p>Initialize the factory used to create the module configuration.</p>

     * @since Struts 1.2

     */

protected void initModuleConfigFactory(){

/**

这个部分的代码就是取得参数。

这个参数你可以自己扩展你的模块实现工厂。但是一般都没有自己去做。

所以一般都使用的默认的工厂初始化配置。

*/

        String configFactory = getServletConfig().getInitParameter("configFactory");

/**

下面的代码,只有你做了自己的配置才会有效。否则一般是不执行的。

*/

        if (configFactory != null) {

/**

设置此工厂,并把其参数存入到 ModuleConfigFactory.factoryClass 属性中。

此部分可以看 ModuleConfigFactory 的代码。 ModuleConfigFactory 是一个

*/

            ModuleConfigFactory.setFactoryClass(configFactory);

        }

    }

b.       资源模块式如何初始化的

// 调用的部分

protected String config = "/WEB-INF/struts-config.xml";

------------------------------------------------------------------          

ModuleConfig moduleConfig = initModuleConfig("", config);

initModuleMessageResources(moduleConfig);

       // 实现的部分:

    protected void initModuleMessageResources (ModuleConfig config)

        throws ServletException {

              /**

       struts-config.xml 中的资源文件配置,你可能配置了多个资源,所以此处取得是一个数组

*/

        MessageResourcesConfig mrcs[] = config.findMessageResourcesConfigs();

 

        for (int i = 0; i < mrcs.length; i++) {

            if ((mrcs[i].getFactory() == null)

                || (mrcs[i].getParameter() == null)) {

                continue;

            }

            if (log.isDebugEnabled()) {

                log.debug(

                    "Initializing module path '"

                        + config.getPrefix()

                        + "' message resources from '"

                        + mrcs[i].getParameter()

                        + "'");

            }

/**

           protected String factory =

        "org.apache.struts.util.PropertyMessageResourcesFactory";

就是返回的这个值,如果你没有做其他的设置的话。

一般情况下,我们都用得是默认的

*/

            String factory = mrcs[i].getFactory();

/**

       此处对每一个资源配置文件都回去创建一个工厂

*/

            MessageResourcesFactory.setFactoryClass(factory);

            MessageResourcesFactory factoryObject =

                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(mrcs[i]);

            MessageResources resources =

                factoryObject.createResources(mrcs[i].getParameter());

            resources.setReturnNull(mrcs[i].getNull());

            resources.setEscape(mrcs[i].isEscape());

 

       /**

这一部分非常重要。

我们之所以能够直接调用,就是因为,初始化后,我们就把此 resources 放到了其对应的当前应用的属性值里面了。之后我们就可以直接调用了。
       */

            getServletContext().setAttribute(

                mrcs[i].getKey() + config.getPrefix(),

                resources);

        }

 

    }

c.       数据模块是如何初始化的

==========================================================

// 调用部分

initModuleDataSources(moduleConfig);

 

// 实现部分:

/**

     * <p>Initialize the data sources for the specified module.</p>

     *

     * @param config ModuleConfig information for this module

     *

     * @exception ServletException if initialization cannot be performed

     * @since Struts 1.1

     */

    protected void initModuleDataSources(ModuleConfig config) throws ServletException {

 

        // :FIXME: Document UnavailableException?

 

        if (log.isDebugEnabled()) {

            log.debug("Initializing module path '" + config.getPrefix() +

                "' data sources");

        }

 

        ServletContextWriter scw =

            new ServletContextWriter(getServletContext());

/**

因为你可能配置了多个数据源,所以此处返回的是一个数组
*/

        DataSourceConfig dscs[] = config.findDataSourceConfigs();

    // 处理没有配置数据源的情况

if (dscs == null) {

dscs = new DataSourceConfig[0];

        }

/**

           /**

     * <p>The JDBC data sources that has been configured for this module,

     * if any, keyed by the servlet context attribute under which they are

     * stored.</p>

     */

protected FastHashMap dataSources = new FastHashMap();

这是一个加工过的 HashMap ,又不同的工作模式

 

*/

 

        dataSources.setFast(false);

        for (int i = 0; i < dscs.length; i++) {

            if (log.isDebugEnabled()) {

                log.debug("Initializing module path '" + config.getPrefix() +

                    "' data source '" + dscs[i].getKey() + "'");

            }

            DataSource ds = null;

            try {

          /**

*/

   ds = (DataSource)

                    RequestUtils.applicationInstance(dscs[i].getType());

                BeanUtils.populate(ds, dscs[i].getProperties());

                ds.setLogWriter(scw);

 

            } catch (Exception e) {

                log.error(internal.getMessage("dataSource.init", dscs[i].getKey()), e);

                throw new UnavailableException

                    (internal.getMessage("dataSource.init", dscs[i].getKey()));

            }

/**

       这一个部分很重要。

       把初始化后的数据源放入到 servlet 的属性中,所以我们才可以通过 struts 的对应属性直接访问。

  protected String key = Globals.DATA_SOURCE_KEY;

所以,我们可以通过 Globals.DATA_SOURCE_KEY 属性的值来取得其配制后的数据源。

如果多个的话,可以通过数据源的参数 ID 来配置和调用。

*/

            getServletContext().setAttribute

                (dscs[i].getKey() + config.getPrefix(), ds);

            dataSources.put(dscs[i].getKey(), ds);

        }

 

        dataSources.setFast(true);

 

    }

 

至此,Struts系统初始化完毕。

  评论这张
 
阅读(390)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017