Struts调用的BeanUtils反射的基本原理

import java.lang.reflect.Method;  
import java.sql.Date;  
public class Methoder {  
    /** 
     * @param args 
     */  
    public static void main(String[] args) throws Exception {  
        Class<?> clazz = Class.forName("InvokedClass");  
        Object o = clazz.newInstance();  
          
        Class<?> types[] = new Class[3];  
        types[0] = Class.forName("java.lang.String");  
        types[1] = Class.forName("java.sql.Date");  
        types[2] = int.class;  
        Method m = clazz.getDeclaredMethod("sayHello", types);  
        m.invoke(o, "libram", Date.valueOf("1988-8-8"), 19);  
          
        System.out.println(o.toString());  
    }  
}  
class InvokedClass {  
    private String name;  
    private Date birth;  
    private int age;  
    public void sayHello(String name, Date birth, int age) {  
        this.name = name;  
        this.birth = birth;  
        this.age = age;  
    }  
    public String toString() {  
        return "name = " + name + "\tbirth = " + birth.toString() + "\tage = "  
                + age;  
    }  
}  

模拟struts中的DispatchAction

package org.lbr.action;

import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class MyDispatch extends Action {

 @Override
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  response.setCharacterEncoding("GBK");
  PrintWriter out = response.getWriter();

  String parameterName = mapping.getParameter();
  String parameterValue = request.getParameter(parameterName);
  if (parameterValue.equals("")) {
   out.println(parameterName + "指定的属性值为空!");
  } else if (parameterValue.equals("execute")) {
   out.println("指定的属性值不能为 execute");
  } else {
   Class<?>[] types = new Class<?>[4];
   types[0] = Class.forName("org.apache.struts.action.ActionMapping");
   types[1] = Class.forName("org.apache.struts.action.ActionForm");
   types[2] = Class.forName("javax.servlet.http.HttpServletRequest");
   types[3] = Class.forName("javax.servlet.http.HttpServletResponse");

   try {
    Method method = this.getClass()
      .getMethod(parameterValue, types);
    if (method != null) {
     return (ActionForward) method.invoke(this, mapping, form,
       request, response);
    }
   } catch (NoSuchMethodException e) {
    throw new Exception("\n没有找到名为 \npublic ActionForward "
        + parameterValue
        + "(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception\n的方法");
   } catch (SecurityException e) {
    throw e;
   }
  }

  return null;
 }

}

ActionConfig ActionMapping ActionForward ForwardConfig关系

ActionConfig  ActionMapping  ActionForward   ForwardConfig

四个类之间的关系图:

为什么要分别让ActionMapping和ActionForward分别继承ActionConfig与ForwardConfig?

ActionConfig和ForwardConfig分别包装了struts-config.xml中<action>标签和<forward>标签中的内容,一方面他们是一个关于struts设置的bean包装类,只要求提供自己属性的一些setter和getter方法,不能做过多的事情,另一方面,由于如果直接把ActionMapping中的findForward()方法放到ActionConfig中的话,那么设置在<global-forwards>中的<forward>内容就找不到了,这种高层鸟瞰的方法可以在高处对底层的bean形成一个更好的包装。