本文按照1.构造函数->2.init()->3.do*()->4.destroy()的顺序,解析ActionServlet的工作原理。
init()的初始化工作分为个步骤进行:
1.initInternal()资源文件的初始化

protected String internalName = "org.apache.struts.action.ActionResources";
protected void initInternal(){
internal 
= MessageResources.getMessageResources(internalName);//初始化资源文件信息,通过工厂模式取得一个单例的资源
}


internalName与initInternal()都是protected所以可以被子类重载。修改struts默认的资源文件信息。
2.initOther()根据web.xml的配置参数执行不同的初始化,1.设置struts配置文件路径2.convertNull

protected void initOther()throws ServletException {
        String value;
        value 
= getServletConfig().getInitParameter("config");
        
if (value != null{
            config 
= value; //设置struts配置文件路径
        }
     
        value 
= getServletConfig().getInitParameter("convertNull");
        
if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
            
|| "on".equalsIgnoreCase(value) || "y".equalsIgnoreCase(value)
            
|| "1".equalsIgnoreCase(value)) {
            convertNull 
= true;
        }

        
if (convertNull) //如果convertNull为true\on\yes\y\1执行
            ConvertUtils.deregister();
            ConvertUtils.register(
new BigDecimalConverter(null),BigDecimal.class);
           ……
        }

    }

  
3.initServlet()解析servletName,url-Pattern。官方struts的web.xml:servletName=action,urlPattern=/*.do

 

protected void initServlet()throws ServletException {         
        
this.servletName = getServletConfig().getServletName();//取得设置servletName
        /*digester主要是实现对xml的访问,许多功能强大的常用操作都已经封装了起来。*/
        Digester digester 
= new Digester();
        digester.push(
this);
        digester.setNamespaceAware(
true);
        digester.setValidating(
false);
        
for (int i = 0; i < registrations.length; i += 2{
            URL url 
= this.getClass().getResource(registrations[i + 1]);
            
if (url != null{
                digester.register(registrations[i], url.toString());
            }

        }

        
/*以下3句的意思是当遇到web-app/servlet-mapping时执行addServletMapping函数(下面有该函数的源码),这个方法有两个参数,第一个是web-app/servlet-mapping/servlet-name标签里的,第二个是web-app/servlet-mapping/url-pattern标签里的.parse (input)开始解析。实际上这段陌生的代码只是执行了addServletMapping(servlet-name,url-pattern);servlet-name,url-pattern分别从/WEB-INF/web.xml中取得*/
        digester.addCallMethod(
"web-app/servlet-mapping""addServletMapping"2);
        digester.addCallParam(
"web-app/servlet-mapping/servlet-name"0);
        digester.addCallParam(
"web-app/servlet-mapping/url-pattern"1);
        InputStream input 
=
            getServletContext().getResourceAsStream(
"/WEB-INF/web.xml"); 
        digester.parse(input);        
        
if (servletMapping != null{
            getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);
        }

    }

    

 

/*在initServlet()中被调用*/
    
public void addServletMapping(String servletName, String urlPattern) {
        
if (servletName == null{
            
return;
        }

        
/*一般而言servletName=action,urlPattern=/*.do*/
        
if (servletName.equals(this.servletName)) {
            
if (log.isDebugEnabled()) {
                log.debug(
"Process servletName=" + servletName
                    
+ ", urlPattern=" + urlPattern);
            }


            
this.servletMapping = urlPattern;
        }

    }

 

(初始化工作还未完成,待续)