使用javassist获取类方法参数名称

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Majker/article/details/88809579

动态获取某个类的方法参数名,借助javassist.jar包可以获取。

1、pom.xml

<dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.20.0-GA</version>
</dependency>

2、单元测试类(重点)

  • private Map<String, Object> getMethodParams(Map<String, Object> handlerMap) ;

  • public static String[] getMethodParams(String classname, String methodname) ;

import com.majker.modules.controller.UserController;
import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import org.junit.Test;

import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

/****************************************************
*
*  获取方法参数名 测试
*
* @author majker
* 
* @version 1.0
**************************************************/
public class TestJunit {

   /**
    * 获取指定方法的参数名  参数类型
    *
    * @throws Exception
    */
   @Test
   public void test1() throws Exception {
       Map<String, Object> paramMap = new LinkedHashMap<>();

       //获取类的class对象
       Class<UserController> clazz = UserController.class;
       paramMap.put("clazz", clazz);

       //获取类中的方法实体
       Method method = clazz.getMethod("testAdd", String.class);
       paramMap.put("method", method);

       //调用方法获取参数名
       Map<String, Object> methodParams = getMethodParams(paramMap);

       //遍历
       System.out.println("类:" + clazz.getName());
       System.out.println("方法名:" + method.getName());
       for (String in : methodParams.keySet()) {
           System.out.println("参数名:" + in);
           System.out.println("参数类型:" + methodParams.get(in).toString());
       }
   }


   /**
    * 获取类中方法的参数名 参数类型
    *
    * @throws Exception
    */
   @Test
   public void test2() throws Exception {
       Method[] methods = UserController.class.getDeclaredMethods();
       for (Method m : methods) {
           System.out.print("方法名" + m.getName() + "\t");
           Map<String, Object> paramMap = new LinkedHashMap<>();
           paramMap.put("clazz", UserController.class);
           paramMap.put("method", m);
           Map<String, Object> methodParams = getMethodParams(paramMap);
           for (String in : methodParams.keySet()) {
               //参数类型
               Class o = (Class) methodParams.get(in);
               System.out.print(in + " ");
           }
           System.out.println();
       }
   }

   /**
    * 通过类名 方法名 获取参数名
    *
    * @throws Exception
    */
   @Test
   public void test3() {
       String className = "com.majker.modules.controller.UserController";
       String methodName = "testAdd";
       String[] methodVariableName = getMethodParams(className, methodName);
       for (String s : methodVariableName) {
           System.out.println(s);
       }
   }

   /***
    * 使用javaassist的反射方法获取方法的参数名
    *
    * @param handlerMap
    *          clazz:类的class对象
    *          method :方法的Method对象
    *
    * @return
    */
   private Map<String, Object> getMethodParams(Map<String, Object> handlerMap) {
       Class<?> clazz = (Class) handlerMap.get("clazz");
       Method method = (Method) handlerMap.get("method");
       Map<String, Object> params = new LinkedHashMap<>();

       try {
           ClassPool pool = ClassPool.getDefault();
           ClassClassPath classPath = new ClassClassPath(this.getClass());
           pool.insertClassPath(classPath);
           CtClass cc = pool.get(clazz.getName());
           CtMethod cm = cc.getDeclaredMethod(method.getName());
           MethodInfo methodInfo = cm.getMethodInfo();
           CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
           LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
           if (attr == null) {
               throw new IllegalArgumentException("获取参数错误");
           }
           int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
           String[] paramNames = new String[cm.getParameterTypes().length];
           Class<?>[] parameterTypes = method.getParameterTypes();
           for (int i = 0; i < paramNames.length; i++) {
               paramNames[i] = attr.variableName(i + pos);
               params.put(paramNames[i], parameterTypes[i]);
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
       return params;
   }

   /***
    *  通过类名 方法名获取方法中的参数名
    *
    * @param classname 类的完整路径
    * @param methodname  方法名
    * @return
    */
   public static String[] getMethodParams(String classname, String methodname) {
       try {
           ClassPool pool = ClassPool.getDefault();
           CtClass cc = pool.get(classname);
           CtMethod cm = cc.getDeclaredMethod(methodname);
           MethodInfo methodInfo = cm.getMethodInfo();
           CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
           String[] paramNames = new String[cm.getParameterTypes().length];
           LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
           if (attr != null) {
               int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
               for (int i = 0; i < paramNames.length; i++) {
                   paramNames[i] = attr.variableName(i + pos);
               }
               return paramNames;
           }
       } catch (Exception e) {
           System.out.println("getMethodVariableName fail " + e);
       }
       return null;

   }

}

3、 测试实体类


package com.majker.modules.controller;

import com.majker.common.annotation.Controller;
import com.majker.common.annotation.ModelAttribute;
import com.majker.common.annotation.RequestMapping;
import com.majker.common.annotation.RequestMethod;
import com.majker.modules.entity.User;
import com.majker.common.util.DBHelp;
import com.majker.common.mvc.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.UUID;
 /****************************************************
  *
  *     handler  后端控制器
  *
  * @author majker
  *
  * @version 1.0
  **************************************************/
@Controller
@RequestMapping("/user")
public class UserController {

    @ModelAttribute
    public void index(){
        System.out.println("先执行了");
    }

    @RequestMapping("/list")
    public ModelAndView list(HttpServletRequest request, HttpServletResponse response,ModelAndView model){
        User currentUser = new User(UUID.randomUUID().toString(),"majker","1");
        List<User> list = DBHelp.qunery(currentUser);
        model.addObject("list",list);
        model.setView("userList");
        return model;
    }

    @RequestMapping("/add")
    public String add(){
        return "userAdd";
    }

    @RequestMapping(value = "/doAdd",method = RequestMethod.POST)
    public ModelAndView doAdd(String username, String password, ModelAndView model){
        User user = new User();
        user.setId(UUID.randomUUID().toString());
        user.setName(username);
        user.setPassword(password);
        user.setSex("1");
        DBHelp.insert(user);
        //拿到用户名跟密码,去服务层做一些不可描述的事情
        model.addObject("info","用户添加成功,用户名:"+username+",密码:"+password);
        List<User> list = DBHelp.qunery(new User());
        model.addObject("list",list);
        model.setView("userList");
        return model;
    }

    public void testAdd(String name){

    }

}

4、测试运行结果截图

4.1 测试1结果

在这里插入图片描述

4.2 测试2结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Majker/article/details/88809579
今日推荐