Author : zhyiwww
E-Mail : zhyiwww@163.com
Date : 2007-1-10
转载请注明出处
(copyright by @ zhangyi)
Struts中的MessageResource、PlugIn、数据源等,都是通过ModuleConfig来实现的。
那么在ActionServlet初始化上面的那些模块之前,就先要初始化ModuleConfig,然后由ModuleConfig来负责其初始化。
在ActionServlet初始化ModuleConfig的时候,先要初始化配置工厂,然后由配置工厂:
initModuleConfigFactory();
之后再实例化一个ModuleConfig的对象。
ModuleConfig moduleConfig = initModuleConfig("", config);
那么这个工厂到底初始化了什么?
现看源代码:
protected void initModuleConfigFactory(){
String configFactory = getServletConfig().getInitParameter("configFactory");
if (configFactory != null) {
ModuleConfigFactory.setFactoryClass(configFactory);
}
}
很明显,现从配置参数取得其配置,如果用户没有作配置,那么就使用默认配置,如果用户作了配置,那么就使用用户的配置。
如果用户作了配置的话,那么就执行设置成用户的工厂。如何设置的呢?
public static void setFactoryClass(String factoryClass) {
ModuleConfigFactory.factoryClass = factoryClass;
ModuleConfigFactory.clazz = null;
}
在此我们可以看到,直接给ModuleConfigFactory.factoryClass赋值,为什么可以这样做呢?因为此变量是:
protected static String factoryClass =
"org.apache.struts.config.impl.DefaultModuleConfigFactory";
由此定义决定了可以使用此赋值方法。因为此变量是一个静态的变量。
正是因为此变量是一个静态的变量,所以在下面的得工厂生成对象的时候就可以创建一个用户自己的对象。
看一下是如何初始化ModuleConfig,看下面的源代码:
protected ModuleConfig initModuleConfig(String prefix, String paths)
throws ServletException {
/*************************************************************
这个地方,我们可以看到,此时就由ModuleConfigFactory直接创建了一个工厂对象,而此时我们用的配置就是上面我们初始化后的配置。
如果用户自己做了配置,那么此时初始化的工厂就是用户指定后的工厂。如果没有的话,那么就初始化的时默认的工厂。
也就是
protected static String factoryClass =
"org.apache.struts.config.impl.DefaultModuleConfigFactory";
的一个实例。
*************************************************************/
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;
}
那么初始化配置模块的部分到底做了什么呢?
其实是生成了一个ModuleConfig的对象。这个对象是由其工厂产生的,由什么样的工厂就会生成什么样的产品。所以如果是用户配置过的工厂,那么就会生成其对应的配置模块的实现。
先看默认的情况:
public class DefaultModuleConfigFactory extends ModuleConfigFactory implements Serializable{
// --------------------------------------------------------- Public Methods
/**
* Create and return a newly instansiated {@link ModuleConfig}.
* This method must be implemented by concrete subclasses.
*
* @param prefix Module prefix for Configuration
*/
public ModuleConfig createModuleConfig(String prefix) {
return new ModuleConfigImpl(prefix);
}
}
通过其默认工厂的实现,我们可以看到,其实例化了一个ModuleConfigImpl的对象,这是ModuleConfig的一种实现,也是当前struts的默认的实现。
如果是用户配置了实现工厂的话,可能的实现就是:
public class UserModuleConfigFactory extends ModuleConfigFactory implements Serializable{
public ModuleConfig createModuleConfig(String prefix) {
return new ModuleConfigUserImpl(prefix);
}
}
当然,如果要启用你的工厂的话,那么还要在你的配置文件中添加如下部分,在web.xml中修改如下部分:
action
org.apache.struts.action.ActionServlet
config
/WEB-INF/struts-config.xml
debug
3
detail
3
configFactory
org.aa.struts. UserModuleConfigFactory
0
这样的话,你的工厂就可以生效了,也可以生成你自己的配置模块的实例了。
到此,配置模块的初始化也已经完成,下面就是要实现如何对各个不同的模块进行初始化了。
【责编:Peng】
--------------------next---------------------