使用javassist获取类方法参数名称
动态获取某个类的方法参数名,借助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){
}
}