读书人

JpetStore中MVC机制兑现的研究,BeanAc

发布时间: 2012-10-09 10:21:45 作者: rapoo

JpetStore中MVC机制实现的研究,BeanAction以及BaseBean工作机制(看完有种恍然大悟的感觉啊!)

以前学习iBATIS时候只是粗略的看了一下代码,今天翻出来从新看了看,才发现iBATIS给的JpetStore中关于iBATIS的实现简直太精妙了,它直接把action和actionform合并在一起~JpetStore中MVC机制兑现的研究,BeanAction以及BaseBean工作机制(看完有种恍然大悟的感觉啊)very good!!!

JpetStore的src文件夹,并无一个具体的Action,那么它是如何来完成普通Struts的Action工作了?
查看JpetStore的struts-config.xml可以发现,它的Action只有一个,即“org.apache.stuts.beanaction.Beanaction”。通过Eclipse查看直接跳转到beanaction.jar的源代码,可以发现Beanaction继承了普通Action,即具备普通的action的功能。那么它具体Action的奥妙在哪,继续研究BeanAction的代码,发现BeanAction其实只有一个方法,源代码如下:

public final ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {    String forward = SUCCESS_FORWARD;    try {      if (!(form instanceof BaseBean)) {        if (form != null) {          throw new BeanActionException("The form for mapping '" + mapping.getPath() + "' named '" + mapping.getName() + "' was not an instance of BaseBean.  BeanAction requires an BaseBean instance.");        } else {          throw new BeanActionException("The form for mapping '" + mapping.getPath() + "' named '" + mapping.getName() + "' was null.  BeanAction requires an BaseBean instance.");        }      }      BaseBean bean = (BaseBean) form;      ActionContext.initCurrentContext(request, response);      if (bean != null) {        // Explicit Method Mapping        Method method = null;        String methodName = mapping.getParameter();        if (methodName != null && !NO_METHOD_CALL.equals(methodName)) {          try {            method = bean.getClass().getMethod(methodName, null);            synchronized (bean) {              forward = bean.getInterceptor().intercept(new ActionInvoker(bean, method));            }          } catch (Exception e) {            throw new BeanActionException("Error dispatching bean action via method parameter ('" + methodName + "').  Cause: " + e, e);          }        }        // Path Based Method Mapping        if (method == null && !NO_METHOD_CALL.equals(methodName)) {          methodName = mapping.getPath();          if (methodName.length() > 1) {            int slash = methodName.lastIndexOf("/") + 1;            methodName = methodName.substring(slash);            if (methodName.length() > 0) {              try {                method = bean.getClass().getMethod(methodName, null);                synchronized (bean) {                  forward = bean.getInterceptor().intercept(new ActionInvoker(bean, method));                }              } catch (Exception e) {                throw new BeanActionException("Error dispatching bean action via URL pattern ('" + methodName + "').  Cause: " + e, e);              }            }          }        }      }    } catch (Exception e) {      forward = "error";      request.setAttribute("BeanActionException", e);    }    return mapping.findForward(forward);  }

?最关键的地方应该就是这里:

/*通过反射,根据得到的方法名称取得方法的句柄*/             method = bean.getClass().getMethod(methodName, null);             synchronized (bean) { /*下面是关键一句,调用basebean拥有的接口ActionInterceptor的实现DefaultActionInterceptor,来完成具体方法的调用*/               forward = bean.getInterceptor().intercept(new ActionInvoker(bean, method));             } 

?而ActionInvoker中

public String invoke() {    try {      return (String) method.invoke(bean, null);    } catch (Exception e) {      throw new BeanActionException("Error invoking Action.  Cause: " + e, e);    }  }

?至此可知,它调用的是formbean中的函数。且从这段代码可知,formbean的这类特殊函数,此处称为action方法,要符合两个特征:1)无参数;2)返回值为string,此返回string即是struts-config.xml的全局或局部的forward。

?

高手估计会不屑一顾,但是新手们绝对有用,还有不懂的可以看iBATIS实战中的第14章,非常经典http://book.csdn.net/bookfiles/700/

这个网站有免费试读。

读书人网 >VC/MFC

热点推荐