为抽象类ModuleConfigFactory设置一个工厂类 如果配置文件里没有配置configFactory 属性的话服务器启动的时候就不会再这里创建而是通过下面的ModuleConfigmoduleConfig = initModuleConfig("", config);方法创建 创建一个默认的org.apache.struts.config.impl.DefaultModuleConfigFactory工厂类实例,这里的目的是为了开发人员创建自己的moduleConfig类。
这里是先通过ModuleConfigFactory工厂生成一个默认的DefaultModuleConfigFactory对象然后调用该对象的createModuleConfig(Stringprefix)方法 生成一个 ModuleConfigImpl类给ModuleConfig config对象然后再调用initConfigDigester();方法对解析配置文件做准备,初始化Digest类
主要有设置nameSpace,validating,rule,dtd等。其中configDigester.addRuleSet(newConfigRuleSet());中的ConfigRuleSet()是为了解析配置文件得规则类,在addRuleSet()方法中将调用ConfigRuleSet规则类的addRuleInstances()方法。该方法为解析xml添加所需要的继承了Rule接口的类到digester中。
1.digester.addRule("struts-config/action-mappings",new SetActionMappingClassRule());中得SetActionMappingClassRule()类查看action-mappings 元素是否有type属性,如有则set到ModuleConfigImpl中的actionMappingClass.
2.digester.addFactoryCreate("struts-config/action-mappings/action", newActionMappingFactory(cl))的ActionMappingFactory()工厂类查看action元素是否有className 属性,如果有则根据这个className的Value值创建类,否则从ModuleConfigImpl中得到actionMappingClass属性值来创建类,默认得创建ActionMapping类。
3.digester.addSetProperties("struts-config/action-mappings/action");方法将newSetPropertiesRule()这个Rule类加入到Digest中,而SetPropertiesRule类主要作用是将action元素中得属性值set到ActionMapping对应的属性中去。如
<actiοninput="/adminlogin.jsp"name="adminLoginForm"path="/adminLogin"scope="request"type="com.laoer.bbscs.web.action.AdminLogin"validate="true" />中得input的Value就set到ActionMapping中的input属性中去,其他得依次类推。
4.digester.addSetNext("struts-config/action-mappings/action","addActionConfig","org.apache.struts.config.ActionConfig");方法的主要功能是将调用digester类push第一个push进的那个类的addActionConfig方法,并有参数为ActionConfig类型为在这里这个类是ModuleConfigImpl,同时传进去参数为ActionMapping类
5.digester.addRule("struts-config/action-mappings/action/set-property", newBaseConfigSetPropertyRule());而BaseConfigSetPropertyRule类主要作用是如果action元素下有子元素set-property并且没有拥有属性Key 则将set-property元素的属性 property =”XXX”中的XXX为ActionMapping类的属性,Value=”YYYY”为XXX得Value值 set进ActionMapping中。如果拥有Key属性的话则存到Properties中去。
6.digester.addObjectCreate("struts-config/action-mappings/action/exception","org.apache.struts.config.ExceptionConfig", "className");方法主要功能是在元素action中有子元素exception,并以元素exception得属性className中的valueXXXX值为基础生成XXXX类,如果className属性值为空,则默认生ExceptionConfig类。
我们再回到调用ConfigRuleSet类addRuleInstances()方法的得initConfigDigester()方法,接下来是configDigester.register(registrations[i],url.toString())方法,该方法将关于struts-config.xml得DTD文件set到Digester中得entityValidator属性中去。以便以后解析配置文件的时候对文件有效性进行校验。
在addRuleInstances()方法中主要是这几个方法,其他得处理逻辑与以上方法相似。
?
this.addRuleSets()类则从web.xml中如果配置了rulesets属性则初始化客户化的RuleSet。
好到此为之,Digest得准备工作已经完成,接下来就是应该解析配置文件了。
?
Struts 源码中接下来是看web.xml是否配置了多了struts-congfig.xml文件,如果是则解析多个。解析的代码就在this.parseModuleConfigFile(digester,url)中,该方法就是解析配置文件得关键,其实该方法就一个方法,即digester.parse(url);但是它得作用确是非凡的,主要工作流程是以下几点
1. 调用Digester的public voidstartElement(String namespaceURI, String localName,String qName, Attributeslist)方法。至于为什么会调用这个方法是因为Digester继承了ContentHandler接口而接口是sax在解析配置文件会调startElement()方法,该方法把上面提及得digester实例中在ConfigRuleSet类中addRuleInstances()保存到digester中得Rule类找出来并且调用其Rule类的begin()方法。现在我们拿3个Rule来解释说明
在ConfigRuleSet中的addRuleInstances()方法中有
digester.addFactoryCreate("struts-config/form-beans/form-bean", newActionFormBeanFactory(cl));
digester.addSetProperties("struts-config/form-beans/form-bean");
等。。。