【www.gdgbn.com--js教程】

网页特效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);
            }
        }
    }   
//到初始化action类的时候, 你需要去filterdispatcher的dofilter方法去看代码

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 t getinstance(final class type) {

    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 contextmap) {  
        // load action  
        string timerkey = "actioncreate: " + proxy.getactionname();  
       ……  
action =  
 objectfactory.buildaction(proxy.getactionname(), proxy.getnamespace(), proxy.getconfig(), contextmap);  
      …… 

protected void createaction(map contextmap) {
        // 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 extracontext)   
throws exception {  
        return buildbean(config.getclassname(), extracontext);  
    }  
                      
      
public object buildbean(string classname, map extracontext, boolean injectinternal) throws exception {  
        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 extracontext) throws exception {  
        return clazz.newinstance();  
   }     

public object buildaction(string actionname, string namespace, actionconfig config, map extracontext)
throws exception {
        return buildbean(config.getclassname(), extracontext);
    }
              
 
public object buildbean(string classname, map extracontext, boolean injectinternal) throws exception {
        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 extracontext) throws exception {
        return clazz.newinstance();
   }  ok, 整体来说,这个问题说清楚很难,因为你无法记住你追踪到的所有的类,但是有一点是肯定的,那就是流程: 基本上我的理解就是 通过一系列配置文件的初始化,将文件转换成对象,加载进内存中,再在处理请求时候(注意,只有当filterdispatcher的dofilter第一次被调用时,才会去初始化action类),加载action类来进行业务处理。

本文来源:http://www.gdgbn.com/wangyezhizuo/25565/