Struts 源码学习初始化属性资源文件的过程

开发 后端
本文为struts 源码学习,主要涉及初始化属性资源文件的过程。资源文件分为内部资源文件和外部资源文件。

资源文件,不过是strus架构内部使用的,还是用户自己定义的资源文件,都是资源文件。之所以会用到资源文件,有两个原因:

一是方面是系统通过配置来实现,那么就会有更好的扩展性,也会更灵活。

另一个方面,可以实现国际化。

所以我们可能会有一个或多个资源配置文件。

那么资源文件到底是如何实现其初始化的呢? 

内部资源文件和外部资源文件是分开初始化的,其实是使用了不同的初始化方法。内部资源文件是由init()调用initInternal()直接初始化的,而用户的资源文件是通过配置模块实现的。

内部资源文件如何初始化?

protected void initInternal() throws ServletException { 
        try {
            internal = MessageResources.getMessageResources(internalName);
        } catch (MissingResourceException e) {

        }
}


上面的方法就实现了内部资源的初始化。

其实很简单,通过资源文件定位,然后返回成一个MessageResources的对象就OK了。

也就是internal变量,以后通过此变量就可以直接取属性的值了。

那么你可能会问,getMessageResources(internalName)又是如何实现取得资源文件的?

我们再跟踪一下:
   

public synchronized static MessageResources getMessageResources(String config) { 

        if (defaultFactory == null) {
           defaultFactory = MessageResourcesFactory.createFactory();
        }
        return defaultFactory.createResources(config);
    }


很明显,这里面也使用了工厂模式。然后由工厂去生成一个资源MessageResources.

我们可以这样理解,所有的资源其实属于同一类产品,所以他们可是使用同一个工厂。
上面的初始化工厂的部分,我们其实可以看到, MessageResourcesFactory是一个抽象类,其抽象方法正是createResources(config),

那么他的实现是谁呢?这要问我们的工厂,因为你只有知道了工厂,才会知道产品。

所有我们要先知道,我们初始化了一个什么工厂。

所以我们再看:
   

 public static MessageResourcesFactory createFactory() { 

        // Construct a new instance of the specified factory class
        try {
            if (clazz == null)
                clazz = RequestUtils.applicationClass(factoryClass);
            MessageResourcesFactory factory =
                (MessageResourcesFactory) clazz.newInstance();
            return (factory);
        } catch (Throwable t) {
            LOG.error("MessageResourcesFactory.createFactory", t);
            return (null);
        }

    }

其实工厂实由factoryClass决定的。
这在

    protected static String factoryClass = 
        "org.apache.struts.util.PropertyMessageResourcesFactory";

定义了。

所以我们可以看到,其实是PropertyMessageResourcesFactory实现了*.properties文件的初始化。

初始化后的结果在哪?如何去使用呢?

内部资源文件初始化后的结果以MessageResources的实例保存在internal变量上。其定义如下:

protected MessageResources internal = null;

所以只有struts内部能用,我们就不能调用了。

用户的资源文件时如何初始化的呢?

用户的资源文件是通过配置模块ModueConfig来实现的。上面我们已经初始化了一个ModuleConfig了。所以我们就可

以来初始化我们的资源文件了。

initModuleMessageResources(moduleConfig); 

struts的内部分工也是非常明显的。

ModuleConfig用来管理各个不同的模块的配置。

其实,各个由他管理的模块也有自己的配置。

属性资源文件的配置是就是MessageResourcesConfig

此配置的实例由ModuleConfig来管理,所有由ModuleConfig的实例,可以得到所有属性文件配置的实例。

其实是每一个properties文件,就会对应一个MessageResourcesConfig.

所以我们就可以理解下面的部分代码了。

protected void initModuleMessageResources(ModuleConfig config) 
        throws ServletException {

        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()
                        + "'");
            }

这个地方得到是工厂的类的名称。如:

"org.apache.struts.util.PropertyMessageResourcesFactory"
  

通过这个,我们和前面的比较就可以知道,只要是属性文件,就用的都是这个工厂。
   

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

知道了用哪个工厂之后,就可以实例化了,创建一个工厂了。

            MessageResourcesFactory.setFactoryClass(factory); 
            MessageResourcesFactory factoryObject =
                MessageResourcesFactory.createFactory();
            factoryObject.setConfig(mrcs[i]);

        

由工厂生产出一个MessageResources

            MessageResources resources = 
                factoryObject.createResources(mrcs[i].getParameter());
            resources.setReturnNull(mrcs[i].getNull());
            resources.setEscape(mrcs[i].isEscape());
   
          将解析的结果保存在context 中。

            getServletContext().setAttribute(
                mrcs[i].getKey() + config.getPrefix(),
                resources);
        }

}
至此,strtus如何初始化资源文件的过程也完成了。现在我们已经知道了struts初始化属性资源文件的过程。
最终解析的结果是以MessageResources的形式保存在context中。
至于,如何将properties文件解析成MessageResources,详细地过程和实现,再去细细的学习和研究。

【编辑推荐】

  1. 在Eclipse中开发struts应用程序
  2. 手把手教你在Eclipse中配置开发Struts
  3. Eclipse下开发struts完整解决乱码问题
  4. Struts相关背景介绍
  5. 使用Easy Struts for Eclipse开发Struts
责任编辑:张燕妮 来源: 百度空间
相关推荐

2009-06-05 09:40:59

2012-03-13 13:38:42

Java

2021-07-07 05:00:17

初始化源码

2023-08-28 07:25:58

DDE服务器管理器

2023-10-06 20:57:52

C++聚合成员

2022-01-26 11:00:58

源码层面Vue3

2009-11-18 17:53:18

PHP数组初始化

2011-07-07 15:13:42

PHP

2013-06-17 17:02:15

Windows PhoWP开发资源文件

2024-08-14 17:21:34

2012-04-09 13:43:12

Java

2023-11-12 23:08:17

C++初始化

2011-08-15 17:52:21

iPhone应用对象NSString

2021-12-13 00:54:14

组件Vue3Setup

2010-02-05 09:31:23

Ubuntu 配置文件

2009-07-08 11:01:40

Servlet源文件

2011-06-20 14:18:27

Qt 资源 文件

2009-08-21 16:13:27

C#读取资源文件

2012-02-03 09:55:06

Delphi

2011-08-15 14:47:28

Cocoa嵌入资源文件
点赞
收藏

51CTO技术栈公众号