easyopen原理解析——不到100行代码实现一个最精简的easyopen
easyopen的核心代码非常简单,底层是调用method.invoke()方法实现的。最精简的代码如下:
import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 迷你版easyopen * * @author tanghc */ public class MiniEasyopen { @Documented @Retention(RUNTIME) @Target(METHOD) @interface Api { String name() default ""; } static class ApiInfo { private Object handler; private Method method; public ApiInfo(Object handler, Method method) { this.handler = handler; this.method = method; } } // 业务类 static class GoodsService { // 获取商品接口 @Api(name = "goods.get") public String getGoods(String param) { return "your param is " + param; } } // 存放接口信息的地方 Map<String, ApiInfo> map = new ConcurrentHashMap<String, ApiInfo>(); // 注册接口 public void regist() { // 找到bean对象,可以从spring容器中获取 Object[] beans = {new GoodsService()}; for (Object bean : beans) { Class<?> serviceClass = bean.getClass(); Method[] methods = serviceClass.getMethods(); for (Method method : methods) { // 找到注解方法 Api api = method.getAnnotation(Api.class); if (api != null) { System.out.println(String.format("【注册接口%s,%s】", api.name(), method.toString())); map.put(api.name(), new ApiInfo(bean, method)); } } } } // 调用接口 public Object invoke(String name, String param) throws Exception { // 根据方法名找到对应的接口信息 ApiInfo apiInfo = map.get(name); if (apiInfo == null) { throw new IllegalAccessException("调用不存在的服务" + name); } Method method = apiInfo.method; Object handler = apiInfo.handler; return method.invoke(handler, param); } public static void main(String[] args) throws Exception { // 服务启动 MiniEasyopen miniEasyopen = new MiniEasyopen(); // 注册接口 miniEasyopen.regist(); // 请求名,请求参数,假设已经从request中解析出来 String name = "goods.get"; String param = "iphone"; // 方法调用 Object result = miniEasyopen.invoke(name, param); System.out.println("返回结果:" + result); } }
从main方法开始看,服务启动做了注册接口操作,即找到被@Api标记的方法,然后保存这个方法的信息。
调用接口时,根据接口名找到方法信息,然后invoke一下,返回结果。
这个最基本的骨架搭建完之后,可以进行一些额外则操作,比如签名验证、拦截器、方法结果处理操作。
easyopen就是在此基础上逐渐完善起来的。
相关推荐
Lzs 2020-10-23
聚合室 2020-11-16
零 2020-09-18
Justhavefun 2020-10-22
jacktangj 2020-10-14
ChaITSimpleLove 2020-10-06
Andrea0 2020-09-18
周游列国之仕子 2020-09-15
afanti 2020-09-16
88234852 2020-09-15
YClimb 2020-09-15
风雨断肠人 2020-09-04
卖口粥湛蓝的天空 2020-09-15
stulen 2020-09-15
pythonxuexi 2020-09-06
abfdada 2020-08-26
梦的天空 2020-08-25