网页特效p/网页特效p.html target=_blank >jsp教程 struts2的初始化和类的创建
 public xmlconfigurationprovider() {
        this("xwork.xml", true);
}
public class strutsxmlconfigurationprovider 
   extends xmlconfigurationprovider {
 public strutsxmlconfigurationprovider(boolean errorifmissing)
 {
        this("struts.xml", errorifmissing, null);
    }
…… 
//filterdispatch.init():
public void init(filterconfig filterconfig) 
throws servletexception {
        try {
            this.filterconfig = filterconfig;
            initlogging();
            dispatcher = createdispatcher(filterconfig);
            dispatcher.init();////初始化dispatcher.
            dispatcher.getcontainer().inject(this);
            staticresourceloader.sethostconfig(new filterhostconfig(filterconfig));
        } finally {
            actioncontext.setcontext(null);
        }
    } 
 
 // dispatch.init(): 
 //这里是加载配置文件, 真正初始化struts2的action实例还没开始,
public void init() {
     if (configurationmanager == null) {
      configurationmanager = 
new configurationmanager(beanselectionprovider.default_bean_name);
     }
     init_defaultproperties(); // [1]
        init_traditionalxmlconfigurations(); // [2]
        init_legacystrutsproperties(); // [3]
        init_customconfigurationproviders(); // [5]
        init_filterinitparameters() ; // [6]
        init_aliasstandardobjects() ; // [7]
        container container = init_preloadconfiguration();
        container.inject(this);
        init_checkconfigurationreloading(container);
        init_checkweblogicworkaround(container);
        if (!dispatcherlisteners.isempty()) {
            for (dispatcherlistener l : dispatcherlisteners) {
                l.dispatcherinitialized(this);
            }
        }
    } 
public void dofilter(servletrequest req, servletresponse res,
 filterchain chain) throws ioexception, servletexception {
……         
dispatcher.serviceaction(request, response, servletcontext, mapping);
// 再追踪到dispatcher类,看到这个方法:
 public void serviceaction(https教程ervletrequest request,
 httpservletresponse response, servletcontext context,
  actionmapping mapping) throws servletexception {
      ……
     actionproxy proxy =config.getcontainer().getinstance(
                                                      actionproxyfactory.class).
                                                     createactionproxy(namespace, 
                   name, 
                 method, 
                  extracontext,
                   true, false);
……
//java代码
 public void serviceaction(httpservletrequest request,
 httpservletresponse response, servletcontext context,
  actionmapping mapping) throws servletexception {
      ……
     actionproxy proxy =config.getcontainer().getinstance(
                                                      actionproxyfactory.class).
                                                     createactionproxy(namespace, 
                                                                                          name, 
                                                                                        method, 
                                                                                   extracontext,
                                                                                       true, false);
 ……
 
 确的告诉你了, 它的作用就是创建actionproxy,而我们想要知道的是,
他是如何创建的;
而上面代码中的config,实际上是xwork中的.configuration, 如果你打开xwork源代码,你会发现,他其实是一个接口, 真正做处理的,这里是
com.opensymphony.xwork2.config.impl.defaultconfiguration类, 通过它的getcontainer()方法,获取到一个container类型的实例,而container也是一个接口, 其实现类是:
 
  com.opensymphony.xwork2.inject.containerimpl
   他的getinstance(class clazz):
  public 
    return callincontext(new contextualcallable
      public t call(internalcontext context) {
        return getinstance(type, context);
      }
    });
  }
  // 返回的是你传入的对象,而在这里就是:actionproxyfactory(也是接口,真正返回的是com.opensymphony.xwork2.defaultactionproxyfactory)
而现在,到了真正开始处理加载action实例的时候了:
public actionproxy createactionproxy(actioninvocation inv, string namespace, string actionname, string methodname, 
boolean executeresult, boolean cleanupcontext) {
        defaultactionproxy proxy = new defaultactionproxy(inv,
 namespace, actionname, methodname, executeresult, cleanupcontext);
        container.inject(proxy);
        proxy.prepare();
        return proxy;
    }
 
 我们主要关心的是: 
java代码 
protected void prepare()  {   
      ……   
          invocation.init(this);   
……   
    } 
protected void prepare()  {
      ……
          invocation.init(this);
……
 } 
 ok, 我们进去看看,这里发生了什么? 
这里也是面向接口编程,真实情况是,它调用了
com.opensymphony.xwork2.defaultactioninvocation的init(actionproxy)方法
java代码 
public void init(actionproxy proxy) {   
        ……   
  
        createaction(contextmap);   
  
        ……   
    } 
public void init(actionproxy proxy) {
        ……
createaction(contextmap);
        ……
 } 
ok, 我们终于追踪到我们所需要了解的地方了, 到底struts2/xwork的action是如何创建的呢? 
java代码 
protected void createaction(map
        // load action   
        string timerkey = "actioncreate: " + proxy.getactionname();   
       ……   
action =   
 objectfactory.buildaction(proxy.getactionname(), proxy.getnamespace(), proxy.getconfig(), contextmap);   
      …… 
protected void createaction(map
        // load action
        string timerkey = "actioncreate: " + proxy.getactionname();
       ……
action =
 objectfactory.buildaction(proxy.getactionname(), proxy.getnamespace(), proxy.getconfig(), contextmap);
      …… 继续跟进去看看,你会发现, 事情确实如此:
java代码 
public object buildaction(string actionname, string namespace, actionconfig config, map
throws exception {   
        return buildbean(config.getclassname(), extracontext);   
    }   
                       
       
public object buildbean(string classname, map
        class clazz = getclassinstance(classname);//根据action的名字,进行初始化   
        object obj = buildbean(clazz, extracontext);   
//利用反射来做实例初始化.   
        if (injectinternal) {   
            injectinternalbeans(obj);   
        }   
        return obj;   
        }      
 public class getclassinstance(string classname) throws classnotfoundexception {   
        if (ccl != null) {   
            return ccl.loadclass(classname);   
        }   
        return    
classloaderutil.loadclass(classname, this.getclass());   
}      
public object buildbean(class clazz, map
        return clazz.newinstance();   
   }     
public object buildaction(string actionname, string namespace, actionconfig config, map
throws exception {
        return buildbean(config.getclassname(), extracontext);
    }
              
 
public object buildbean(string classname, map
        class clazz = getclassinstance(classname);//根据action的名字,进行初始化
        object obj = buildbean(clazz, extracontext);
//利用反射来做实例初始化.
        if (injectinternal) {
            injectinternalbeans(obj);
        }
        return obj;
     } 
 public class getclassinstance(string classname) throws classnotfoundexception {
        if (ccl != null) {
            return ccl.loadclass(classname);
        }
        return 
classloaderutil.loadclass(classname, this.getclass());
} 
public object buildbean(class clazz, map
        return clazz.newinstance();
   }  ok, 整体来说,这个问题说清楚很难,因为你无法记住你追踪到的所有的类,但是有一点是肯定的,那就是流程: 基本上我的理解就是 通过一系列配置文件的初始化,将文件转换成对象,加载进内存中,再在处理请求时候(注意,只有当filterdispatcher的dofilter第一次被调用时,才会去初始化action类),加载action类来进行业务处理。