java.lang.reflect.Method (java反射机制)

公司Vac方法过滤器使用到反射机制,读取xml配置文件过滤用户访问的方法名是否合法。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        @SuppressWarnings("unchecked")
        Map<Object, Object> requestData = (Map<Object, Object>) httpRequest.getAttribute("requestData");
        String methodName = (String) requestData.get(METHOD);
        //获得bean的配置
        String beanName = mapProtocol.get(methodName).get(BEAN);
        // 去除.符号
        methodName = getMethod(methodName);
        //从spring context中获得bean
        Object instance = getContext(filterConfig).getBean(beanName);
        Class<? extends Object> clazz = instance.getClass();
        Object resultContent = null;
        try {
            Method method = clazz
                    .getDeclaredMethod(methodName, getParamTypes());
            Map params = removeSysParams(requestData);
            resultContent = method.invoke(instance, params);
        } catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof BusinessException) {
                BusinessException serviceExp = (BusinessException) e
                        .getTargetException();
                Assert.throwBPException(serviceExp.getMessageKey(),
                        serviceExp.getMessage());
            }
            e.printStackTrace();
            Assert.throwBPException(INVOCATION_TARGET_EXP, e);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            Assert.throwBPException(ILLEGAL_ARGUMENT_EXP, e);

        }
        catch (IllegalAccessException e) {
            e.printStackTrace();
            Assert.throwBPException(ILLEGAL_ARGUMENT_EXP, e);

        }
        Enumeration enumeration = httpRequest.getAttributeNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement().toString();
            httpRequest.removeAttribute(name);
        }
        httpRequest.setAttribute(RESPONSEDATA, resultContent);

    }

下面是Method类的源代码及说明:

  1. package java.lang.reflect;   
  2.   
  3. import sun.reflect.MethodAccessor;   
  4. import sun.reflect.Reflection;   
  5.   
  6. /**  
  7.  *   
  8.  * 描述方法的类  
  9.  *   
  10.  * 注意使用反射的方式是首先通过  
  11.  * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象  
  12.  * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得  
  13.  * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args)  
  14.  * 这里obj指调用方法的对象,args表示每个参数对应的值  
  15.  *   
  16.  * 例子,一下两种方式的效果是一样的(当然性能不同)  
  17.  * String ost = "lqtest";  
  18.  * String nst = ost.substring(2,6);  
  19.  *   
  20.  * String ost2 = "lqtest";  
  21.  * Class[] types = {int.class, int.class};  
  22.  * Method med = String.class.getMethod("substring", types);  
  23.  * Object[] values ={new Integer(2), new Integer(6)};  
  24.  * String nst2 = (String) med.invoke(ost2, values);  
  25.  *   
  26.  * 使用反射一切都是变化的,类名,方法名,参数列表,都是变量,而不是写死的,他们  
  27.  * 在运行时才知道具体值,而不是编译期  
  28.  *   
  29.  * comment by liqiang  
  30.  *  
  31.  * @author Kenneth Russell  
  32.  * @author Nakul Saraiya  
  33.  */  
  34. public final  
  35. class Method extends AccessibleObject implements Member {   
  36.  //定义此方法的类对象   
  37.     private Class  clazz;   
  38.     private int   slot;   
  39.     //方法名,从1.4开始它变成intern的形式   
  40.     private String  name;   
  41.     //返回类型   
  42.     private Class  returnType;   
  43.     //参数列表   
  44.     private Class[]  parameterTypes;   
  45.     //异常列表   
  46.     private Class[]  exceptionTypes;   
  47.     //方法的描述符   
  48.     private int   modifiers;   
  49.     //处理方法的实际对象   
  50.     private volatile MethodAccessor methodAccessor;   
  51.     //如果当前对象是通过拷贝得到的,则root指向拷贝前的对象   
  52.     private Method              root;   
  53.   
  54.     //调用对象的安全检查的缓存,保存上一个通过检查的调用对象,如果当前的调用对象   
  55.     //不是上一个调用对象则做安全检查   
  56.     private volatile Class      securityCheckTargetClassCache;   
  57.   
  58.     //构造函数   
  59.     Method(Class declaringClass,   
  60.            String name,   
  61.            Class[] parameterTypes,   
  62.            Class returnType,   
  63.            Class[] checkedExceptions,   
  64.            int modifiers,   
  65.            int slot)   
  66.     {   
  67.         this.clazz = declaringClass;   
  68.         this.name = name;   
  69.         this.parameterTypes = parameterTypes;   
  70.         this.returnType = returnType;   
  71.         this.exceptionTypes = checkedExceptions;   
  72.         this.modifiers = modifiers;   
  73.         this.slot = slot;   
  74.     }   
  75.   
  76.     //通过本对象的数据生成一个新对象   
  77.     Method copy() {   
  78.      //通过本对象的数据生成一个新对象   
  79.         Method res = new Method(clazz, name, parameterTypes, returnType,   
  80.                                 exceptionTypes, modifiers, slot);   
  81.         //新对象的root指向原对象   
  82.         res.root = this;   
  83.         //新对象与原对象公用一个MethodAccessor   
  84.         res.methodAccessor = methodAccessor;   
  85.         return res;   
  86.     }   
  87.   
  88.     //返回声明此函数的类   
  89.     public Class getDeclaringClass() {   
  90.  return clazz;   
  91.     }   
  92.   
  93.     //返回方法名   
  94.     public String getName() {   
  95.  return name;   
  96.     }   
  97.   
  98.     //返回描述符   
  99.     public int getModifiers() {   
  100.  return modifiers;   
  101.     }   
  102.   
  103.     //取得返回类型   
  104.     public Class getReturnType() {   
  105.  return returnType;   
  106.     }   
  107.   
  108.     //返回参数列表   
  109.     public Class[] getParameterTypes() {   
  110.  return copy(parameterTypes);   
  111.     }   
  112.   
  113.     //返回异常列表   
  114.     public Class[] getExceptionTypes() {   
  115.  return copy(exceptionTypes);   
  116.     }   
  117.   
  118.     //判断obj是否与当前方法对象相等   
  119.     public boolean equals(Object obj) {   
  120.  if (obj != null && obj instanceof Method) {//如果是方法对象   
  121.   //转型   
  122.      Method other = (Method)obj;   
  123.         
  124.      //定义此方法的类和方法名相等   
  125.      if ((getDeclaringClass() == other.getDeclaringClass())   
  126.   && (getName() == other.getName())) {   
  127.          
  128.   /* Avoid unnecessary cloning */  
  129.   Class[] params1 = parameterTypes;   
  130.   Class[] params2 = other.parameterTypes;   
  131.      
  132.   //比较参数列表   
  133.   if (params1.length == params2.length) {   
  134.       for (int i = 0; i < params1.length; i++) {   
  135.    if (params1[i] != params2[i])   
  136.        return false;   
  137.       }   
  138.       return true;   
  139.   }   
  140.      
  141.      }   
  142.  }   
  143.  return false;   
  144.     }   
  145.   
  146.     //返回hashCode   
  147.     public int hashCode() {   
  148.  return getDeclaringClass().getName().hashCode() ^ getName().hashCode();   
  149.     }   
  150.   
  151.     //方法对象的字符串表示   
  152.     public String toString() {   
  153.  try {   
  154.      StringBuffer sb = new StringBuffer();   
  155.      int mod = getModifiers();   
  156.      if (mod != 0) {   
  157.      //标志符   
  158.   sb.append(Modifier.toString(mod) + " ");   
  159.      }   
  160.      //注意它这里用的是Field方法中显示类的名字,这个方法显示数组类型跟Class.getName()不同   
  161.      //添加返回类型   
  162.      sb.append(Field.getTypeName(getReturnType()) + " ");   
  163.      //添加类名   
  164.      sb.append(Field.getTypeName(getDeclaringClass()) + ".");   
  165.      //添加方法名   
  166.      sb.append(getName() + "(");       
  167.         
  168.      //参数列表   
  169.      Class[] params = parameterTypes; // avoid clone   
  170.      for (int j = 0; j < params.length; j++) {   
  171.   sb.append(Field.getTypeName(params[j]));   
  172.   if (j < (params.length - 1))   
  173.       sb.append(",");   
  174.      }   
  175.      sb.append(")");   
  176.         
  177.      //异常列表   
  178.      Class[] exceptions = exceptionTypes; // avoid clone   
  179.      if (exceptions.length > 0) {   
  180.   sb.append(" throws ");   
  181.   for (int k = 0; k < exceptions.length; k++) {   
  182.       sb.append(exceptions[k].getName());   
  183.       if (k < (exceptions.length - 1))   
  184.    sb.append(",");   
  185.   }   
  186.      }   
  187.      return sb.toString();   
  188.  } catch (Exception e) {   
  189.      return "<" + e + ">";   
  190.  }   
  191.     }   
  192.   
  193.     /**  
  194.      *   
  195.      * 注意使用反射的方式是首先通过  
  196.      * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象  
  197.      * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得  
  198.      * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args)  
  199.      * 如果调用的方法是static的则obj对象为null,如果方法没有参数,则args的长度为0或为null  
  200.      * 如果返回值是原始类型则返回它的封装类,如果返回值是void则返回null  
  201.      */  
  202.     public Object invoke(Object obj, Object[] args)   
  203.  throws IllegalAccessException, IllegalArgumentException,   
  204.            InvocationTargetException   
  205.     {   
  206.         if (!override) {   
  207.             if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {   
  208.              //获得调用对象的Class对象   
  209.                 Class caller = Reflection.getCallerClass(1);   
  210.                    
  211.                 Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))   
  212.                                      ? clazz   
  213.                                      : obj.getClass());   
  214.                 //调用此操作的对象或方法调用作用的对象与缓存不同,则做安全检查   
  215.                 if (securityCheckCache != caller ||   
  216.                     targetClass != securityCheckTargetClassCache) {   
  217.                     Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);   
  218.                     securityCheckCache = caller;   
  219.                     //通过安全检查的调用对象,缓存它供下次调用时使用   
  220.                     securityCheckTargetClassCache = targetClass;   
  221.                 }   
  222.             }   
  223.         }   
  224.            
  225.         if (methodAccessor == null) acquireMethodAccessor();   
  226.         return methodAccessor.invoke(obj, args);   
  227.     }   
  228.   
  229.     //如果此对象是由copy生成的,则对象与生成此对象的对象使用同一个MethodAccessor   
  230.     private void acquireMethodAccessor() {   
  231.         MethodAccessor tmp = null;   
  232.            
  233.         if (root != null) tmp = root.getMethodAccessor();   
  234.         if (tmp != null) {   
  235.             methodAccessor = tmp;   
  236.             return;   
  237.         }   
  238.            
  239.         //不是由copy得来创建MethodAccessor对象   
  240.         tmp = reflectionFactory.newMethodAccessor(this);   
  241.         setMethodAccessor(tmp);   
  242.     }   
  243.   
  244.     //返回MethodAccessor对象   
  245.     MethodAccessor getMethodAccessor() {   
  246.         return methodAccessor;   
  247.     }   
  248.   
  249.     //设置MethodAccessor对象   
  250.     void setMethodAccessor(MethodAccessor accessor) {   
  251.         methodAccessor = accessor;   
  252.         if (root != null) {//如果此对象是由copy的来   
  253.          //递归调用其上级   
  254.             root.setMethodAccessor(accessor);   
  255.         }   
  256.     }   
  257.   
  258.     //生成一个新的Class数组并将原数组内容考到新数组中   
  259.     static Class[] copy(Class[] in) {   
  260.  int l = in.length;   
  261.     
  262.  if (l == 0)   
  263.      return in;   
  264.     
  265.  Class[] out = new Class[l];   
  266.  for (int i = 0; i < l; i++)   
  267.      out[i] = in[i];   
  268.     
  269.  return out;   
  270.     }   
  271. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值