通过反射执行java方法
今天想实现一个功能就是通过一个交互式的环境,执行java函数。
思路
通过Cmd类来定义函数
通过一个Executor类来注册命令并且执行命令
Cmd.class
public class Cmd { public static Response hello(Request request) { return Response.success("hello " + request.getParams().get(0)); } @Data public static class Request { private MapleCharacter player; private List<String> params; } @Builder @Data public static class Response { private boolean success; private String message; public static Response success() { return Response.builder().success(true).message("执行成功").build(); } public static Response success(String message) { return Response.builder().success(true).message(message).build(); } }}CmdExecutor.class
public class CmdExecutor { private static final Map<String, Method> methodMap = new HashMap<>(); public static void init() { StringBuilder sb = new StringBuilder(); Class<Cmd> cmdClass = Cmd.class; for (Method method : cmdClass.getMethods()) { Parameter[] parameters = method.getParameters(); Class<?> returnType = method.getReturnType(); if (parameters.length == 1 && parameters[0].getType() .equals(Cmd.Request.class) && returnType.equals(Cmd.Response.class)) { sb.append(method.getName()).append(","); methodMap.put(method.getName().toLowerCase(), method); } } System.out.printf("注册命令: %s%n", sb); } public static void execute(String cmdLine) { String[] splitCmd = cmdLine.split(" "); List<String> stringList = Arrays.asList(splitCmd); String cmd = stringList.get(0).toLowerCase(); List<String> params = stringList.subList(1, stringList.size()); Method method = methodMap.get(cmd); if (Objects.isNull(method)) { System.out.printf("命令不存在: %s%n", cmd); } Cmd.Request request = new Cmd.Request(); request.setPlayer(null); request.setParams(params); try { Cmd.Response response = (Cmd.Response) method.invoke(null, request); System.out.printf("执行结果: %s%n", response.getMessage()); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } public static void main(String[] args) { init(); execute("hello java"); }}执行结果:
注册命令: hello,执行结果: hello java