Author
???? :????? zhyiwww
E-Mail
????? :????? zhyiwww@163.com
Date
????????? :????? 2007-1-10
转载请注明出处
www.BlogJava.net/zhyiwww
(copyright by @ zhangyi)
一是方面是系统通过配置来实现,那么就会有更好的扩展性,也会更灵活。
另一个方面,可以实现国际化。
所以我们可能会有一个或多个资源配置文件。
那么资源文件到底是如何实现其初始化的呢?
?????? 内部资源文件和外部资源文件是分开初始化的,其实是使用了不同的初始化方法。内部资源文件是由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,详细地过程和实现,再去细细的学习和研究。