easyopen的核心代碼很是簡單,底層是調用method.invoke()
方法實現的。最精簡的代碼以下:java
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標記的方法,而後保存這個方法的信息。spring
調用接口時,根據接口名找到方法信息,而後invoke一下,返回結果。api
這個最基本的骨架搭建完以後,能夠進行一些額外則操做,好比簽名驗證、攔截器、方法結果處理操做。iphone
easyopen就是在此基礎上逐漸完善起來的。this