通过ActionServlet的成员变量configDigester的初始化来深入理解struts-config.xml文件的加载,其中配置信息可以通过org.apache.struts.config.impl.ModuleConfigImpl类描述。

configDigester上注册了RuleSet类为ConfigRuleSet,主要通过覆盖方法public void addRuleInstances(Digester digester)来为digester注册Rule,代码分析如下:

1.处理ModuleConfigImpl对象中的数据源DataSourceConfig对象:
/* 1.1当遇到struts-config/data-sources/data-source开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.DataSourceConfig对象,并入栈;遇到结束标记时对象出栈。*/

digester.addObjectCreate
("struts-config/data-sources/data-source", "org.apache.struts.config.DataSourceConfig", "className");
/*1.2 当遇到struts-config/data-sources/data-source开始标记时根据data-source标记的属性设置栈顶元素对象的属性 */
digester.addSetProperties
("struts-config/data-sources/data-source");

/*1.3 遇到struts-config/data-sources/data-source结束标记时将调用次栈顶元素ModuleConfigImpl对象的addDataSourceConfig方法,将当前栈顶元素DataSourceConfig对象为值,struts-config/data-sources/data-source标记的key属性为键推入到ModuleConfigImpl的HashMap类型成员变量dataSources中。*/
digester.addSetNext
("struts-config/data-sources/data-source", "addDataSourceConfig", "org.apache.struts.config.DataSourceConfig");

/*1.4 将遇到的set-property标记的property属性值为key,value属性值为值添加到栈顶DataSourceConfig对象的HashMap类型成员变量properties中。*/ digester.addRule
("struts-config/data-sources/data-source/set-property", new AddDataSourcePropertyRule());

2.加载ActionMapping对象:
2.1 设置actionMappingClass属性
/*2.1将遇到的action-mappings标记的type属性值设定为栈顶ModuleConfigImpl对象的actionMappingClass成员变量,如果没有定义type属性,则栈顶对象的actionMappingClass成员变量默认设为org.apache.struts.action.ActionMapping。*/
digester.addRule
("struts-config/action-mappings", new SetActionMappingClassRule());

2.2 处理ActionMapping对象
/*2.2.1遇到struts-config/action-mappings/action开始标记时,创建org.apache.struts.action.ActionMapping(默认)对象实例并入栈,遇到结束标记则出栈。*/
digester.addFactoryCreate
("struts-config/action-mappings/action", new ActionMappingFactory());

/* 2.2.2为栈顶的ActionMapping对象设置属性*/
digester.addSetProperties
("struts-config/action-mappings/action");

/*2.2.3遇到struts-config/action-mappings/action的结束标记时调用堆栈次栈顶元素ModuleConfigImpl的addActionConfig方法,以栈顶元素ActionMapping的path属性为key,栈顶元素为值推入ModuleConfigImpl的HashMap成员变量actionConfigs。*/
digester.addSetNext
("struts-config/action-mappings/action", "addActionConfig", "org.apache.struts.config.ActionConfig");

/*2.2.4遇到struts-config/action-mappings/action/set-property开始标记时将其property属性的值对应的栈顶元素ActionMapping对象的属性名称,设置栈顶对象该属性的值为该标记value属性的值*/
digester.addSetProperty
("struts-config/action-mappings/action/set-property", "property", "value");

2.3 处理ActionMapping对象中的ExceptionConfig对象
/*2.3.1当遇到struts-config/action-mappings/action/exception开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建ExceptionConfig对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/action-mappings/action/exception", "org.apache.struts.config.ExceptionConfig", "className");


/*2.3.2 设置栈顶ExceptionConfig对象的属性 */
digester.addSetProperties
("struts-config/action-mappings/action/exception");

/*2.3.3当遇到struts-config/action-mappings/action/exception结束标记时,次栈顶元素ActionMapping调用addExceptionConfig方法,将该exception标记的type属性为键,栈顶ExceptionConfig对象为值,推入ActionMapping对象的HashMap类型成员变量exceptions中。*/
digester.addSetNext
("struts-config/action-mappings/action/exception", "addExceptionConfig", "org.apache.struts.config.ExceptionConfig");

/*2.3.4当遇到struts-config/action-mappings/action/exception/set-propert标记时将该标记的value属性值赋值给栈顶ExceptionConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/action-mappings/action/exception/set-property","property", "value");

2.4 处理ActionMapping对象中的ActionForward对象:
/*2.4.1 当遇到struts-config/action-mappings/action/forward开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.action.ActionForward对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/action-mappings/action/forward", "org.apache.struts.action.ActionForward", "className");

/*2.4.2遇到struts-config/action-mappings/action/forward标记开始标记时设置栈顶ActionForward对象的属性。*/
digester.addSetProperties
("struts-config/action-mappings/action/forward");

/*2.4.3遇到struts-config/action-mappings/action/forward的结束标记时,通过调用次栈顶元素ActionMapping的addForwardConfig方法,将栈顶的ActionForward对象为值,forward标记的name属性为键,推入到ActionMapping对象的HashMap类型的成员变量forwards中。*/
digester.addSetNext
("struts-config/action-mappings/action/forward", "addForwardConfig", "org.apache.struts.config.ForwardConfig");

/*2.4.4当遇到struts-config/action-mappings/action/forward/set-property标记时将该标记的value属性值赋值给栈顶ForwardConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/action-mappings/action/forward/set-property", "property", "value");

3.处理ModuleConfigImp对象中的ControllerConfig对象
/*3.1当遇到struts-config/controller开始标记时,如果声明className属性,则根据className属性值创建对象实例并入栈,否则创建org.apache.struts.config.ControllerConfig对象并入栈。*/
digester.addObjectCreate
("struts-config/controller", "org.apache.struts.config.ControllerConfig", "className");

/*3.2遇到struts-config/controller属性时为栈顶的ControllerConfig对象属性赋值*/
digester.addSetProperties
("struts-config/controller");

/*3.3遇到struts-config/controller结束标记时,通过调用次栈顶ModuleConfigImpl对象将栈顶的ControllerConfig对象赋值给次栈顶元素的controllerConfig成员变量。*/
digester.addSetNext
("struts-config/controller", "setControllerConfig", "org.apache.struts.config.ControllerConfig");

/*3.4遇到struts-config/controller/set-property标记时为栈顶ControllerConfig对象的属性赋值*/
digester.addSetProperty
("struts-config/controller/set-property", "property", "value");

4.处理ModuleConfigImpl对象的ActionFormBean对象
/*4.1当遇到struts-config/form-beans/form-bean标记时创建org.apache.struts.action.ActionFormBean对象,并入栈;遇到结束标记时ActionFormBean对象出栈。*/
digester.addObjectCreate
("struts-config/form-beans/form-bean", "org.apache.struts.action.ActionFormBean", "className");

/*4.2当遇到struts-config/form-beans/form-bean标记时为栈顶的ActionFormBean对象属性赋值。*/
digester.addSetProperties
("struts-config/form-beans/form-bean");

/*4.3当遇到struts-config/form-beans/form-bean结束标记时,调用次栈顶元素ModuleConfigImpl对象的addFormBeanConfig方法,将form-bean的name属性作为键,以栈顶的FormBeanConfig对象为值推入次栈顶元素的HashMap类型成员变量formBeans中。*/
digester.addSetNext
("struts-config/form-beans/form-bean", "addFormBeanConfig", "org.apache.struts.config.FormBeanConfig");

4.4 处理ActionFormBean对象中的FormPropertyConfig对象
/*4.4.1当遇到struts-config/form-beans/form-bean/form-property开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.FormPropertyConfig对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/form-beans/form-bean/form-property", "org.apache.struts.config.FormPropertyConfig", "className");

/*4.4.2 根据标记org.apache.struts.config.FormPropertyConfig的属性设置栈顶对象FormPropertyConfig实例的属性*/
digester.addSetProperties
("struts-config/form-beans/form-bean/form-property");

/*4.4.3 遇到struts-config/form-beans/form-bean/form-property结束标记时将调用次栈顶元素ActionFormBean对象的addFormPropertyConfig方法,将当前栈顶元素FormPropertyConfig对象为值,form-property标记的name属性为键推入到ActionFormBean的HashMap类型成员变量formProperties中。*/
digester.addSetNext
("struts-config/form-beans/form-bean/form-property","addFormPropertyConfig", "org.apache.struts.config.FormPropertyConfig");

/*4.4.4 当遇到struts-config/form-beans/form-bean/form-property/set-property标记时将该标记的value属性值赋值给栈顶FormPropertyConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/form-beans/form-bean/form-property/set-property", "property", "value");

/* 4.5当遇到struts-config/form-beans/form-bean/set-property标记时将该标记的value属性值赋值给栈顶ActionFormBean对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/form-beans/form-bean/set-property", "property", "value");

5.处理ModuleConfigImpl对象的ExceptionConfig对象
/*5.1当遇到struts-config/global-exceptions/exception开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.ExceptionConfig对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/global-exceptions/exception", "org.apache.struts.config.ExceptionConfig", "className");

/*5.2当遇到struts-config/global-exceptions/exception开始标记时为栈顶的ExceptionConfig对象属性赋值。*/
digester.addSetProperties
("struts-config/global-exceptions/exception");

/*5.3遇到struts-config/global-exceptions/exception结束标记时将调用次栈顶元素ModuleConfigImpl对象的addExceptionConfig方法,将当前栈顶元素ExceptionConfig对象为值,struts-config/global-exceptions/exception标记的type属性为键推入到ModuleConfigImpl的HashMap类型成员变量exceptions中。*/
digester.addSetNext
("struts-config/global-exceptions/exception", "addExceptionConfig", "org.apache.struts.config.ExceptionConfig");

/*5.4 当遇到struts-config/global-exceptions/exception/set-property标记时将该标记的value属性值赋值给栈顶ExceptionConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/global-exceptions/exception/set-property", "property", "value");

6.处理ModuleConfigImpl对象的ActionForward对象
/*6.1当遇到struts-config/global-forwards/forward开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.action.ActionForward对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/global-forwards/forward", "org.apache.struts.action.ActionForward", "className");

/*6.2当遇到struts-config/global-forwards/forward开始标记时为栈顶的ExceptionConfig对象属性赋值。*/
digester.addSetProperties
("struts-config/global-forwards/forward");

/*6.3 遇到struts-config/global-forwards/forward结束标记时将调用次栈顶元素ModuleConfigImpl对象的addForwardConfig方法,将当前栈顶元素ActionForward对象为值,struts-config/global-forwards/forward标记的name属性为键推入到ModuleConfigImpl的HashMap类型成员变量forwards中。*/
digester.addSetNext
("struts-config/global-forwards/forward", "addForwardConfig", "org.apache.struts.config.ForwardConfig");

/*6.4当遇到struts-config/global-forwards/forward/set-property标记时将该标记的value属性值赋值给栈顶ForwardConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/global-forwards/forward/set-property", "property", "value");

7.处理ModuleConfigImpl对象的MessageResourcesConfig对象
/*7.1当遇到struts-config/message-resources开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.MessageResourcesConfig对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/message-resources", "org.apache.struts.config.MessageResourcesConfig", "className");

/*7.2当遇到struts-config/message-resources开始标记时为栈顶的MessageResourcesConfig对象属性赋值。*/
digester.addSetProperties
("struts-config/message-resources");

/*7.3 遇到struts-config/message-resources结束标记时将调用次栈顶元素ModuleConfigImpl对象的addMessageResourcesConfig方法,将当前栈顶元素MessageResourcesConfig对象为值,struts-config/message-resources标记的key属性为键推入到ModuleConfigImpl的HashMap类型成员变量messageResources中。*/
digester.addSetNext
("struts-config/message-resources", "addMessageResourcesConfig","org.apache.struts.config.MessageResourcesConfig");

/*7.4 当遇到struts-config/message-resources/set-property标记时将该标记的value属性值赋值给栈顶MessageResourcesConfig对象的成员变量名称为property属性值的成员变量。*/
digester.addSetProperty
("struts-config/message-resources/set-property", "property", "value");

8.处理ModuleConfigImpl对象的PlugInConfig对象
/*8.1当遇到struts-config/plug-in 开始标记时便创建此标记className属性标示的类实例,如果没有className属性,则创建org.apache.struts.config.PlugInConfig对象,并入栈;遇到结束标记时对象出栈。*/
digester.addObjectCreate
("struts-config/plug-in", "org.apache.struts.config.PlugInConfig");

/*8.2 当遇到struts-config/plug-in开始标记时为栈顶的PlugInConfig对象属性赋值。*/
digester.addSetProperties
("struts-config/plug-in");

/*8.3 遇到struts-config/plug-in结束标记时将调用次栈顶元素ModuleConfigImpl对象的addPlugInConfig方法,将当前栈顶元素PlugInConfig对象添加到ModuleConfigImpl的ArrayList类型成员变量plugIns中。*/
digester.addSetNext
("struts-config/plug-in", "addPlugInConfig", "org.apache.struts.config.PlugInConfig");

/*8.4遇到struts-config/plug-in/set-property开始标记时,将struts-config/plug-in/set-property的property属性值作为键,value属性值作为值添加到栈顶元素PlugInConfig对象的Map类型成员变量properties中。*/
digester.addRule
("struts-config/plug-in/set-property", new PlugInSetPropertyRule());

总结:上述工作实现了xml标记到struts1相关配置对象的映射,总共涵盖了八个部分,即struts-config_1_1.dtd第一层中定义的8个元素:
<!ELEMENT struts-config (data-sources?, form-beans?, global-exceptions?, global-forwards?, action-mappings?, controller?, message-resources*, plug-in*)>
当为ActionServlet的configDigester变量配置完上述规则并执行parse方法后,便可完成一个ModuleConfigImpl对象的初始化。Struts1也支持自定义的RuleSet,通过在ActionServlet初始化参数中定义名称为rulesets的参数,参数值为逗号隔开的RuleSet的全名称。