1. 程式人生 > >手寫一個輕量級的閘道器API

手寫一個輕量級的閘道器API

以HTTP介面形式的應用,是目前大部分中小型企業最常見的微服務誇語言互動的實現方式

即:定義多個介面,外部呼叫,經閘道器解析進行分發,小編遇到的這種情況是,有多個服務,每個服務都需要單獨有閘道器開牆,很是頭疼,每上線一個服務都需要閘道器配置,極其頭疼,再次實現一種暴露一個介面,通過引數來實現呼叫不同的方法的案例,

注意:改方案只適合學習,不適合線上專案

目錄

思路分析

流程圖

實現方案:

    1. 自定義註解 APiMapping
    2. 自定義ApiGateWayServlet
    3. 利用 Spring IOC 拆分方法並與 ApiMaping 做繫結由 ApiStore中HashMap維護

註解定義及利用IOC繫結註解與方法

api註解: APIMapping

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface APIMapping {
    String value();
    RequestMethod method();
}

通過註解對業務方法標記

  @APIMapping(value = "biz.api.order",method = RequestMethod.GET)
    public OrderInfo getOrderInfo
(String orderId) { OrderInfo orderInfo = OrderInfo.builder().id(orderId).name("測試訂單").price(12.2).build(); return orderInfo; } @APIMapping(value = "biz.api.order2",method = RequestMethod.POST) public OrderInfo getOrderDo(OrderInfo orderInfo){ return orderInfo; }

利用Spring 上下文對標記的方法進行繫結
初始化時候,掃描APIMapping介面

 String[] names = applicationContext.getBeanDefinitionNames();
        Class<?> type;
        for (String name : names) {
            type = applicationContext.getType(name);
            for (Method method : type.getDeclaredMethods()) {
                APIMapping apiMapping = method.getDeclaredAnnotation(APIMapping.class);
                if (apiMapping!=null){
                    addApiItem(apiMapping,name,method);
                }
            }
        }

重寫自定義Servlet方法中的POST和GET

public class ApiGateWayServlet extends HttpServlet {
    private ApplicationContext applicationContext;

    private ApiGateWayHandler apiGateWayHandler;

    @Override
    public void init() throws ServletException {
        super.init();
        applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        apiGateWayHandler = applicationContext.getBean(ApiGateWayHandler.class);

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        apiGateWayHandler.handle(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        apiGateWayHandler.handle(req,resp);
    }
}

根據介面繫結獲取到執行的方法,利用反射執行

 public class ApiRunnable {
        private String apiName;
        private Method targetMethod;
        private String targetName;
        private Object target;
        private String Method;
 Object result = null;
        Object target = apiRunable.getTarget();
        Method targetMethod = apiRunable.getTargetMethod();
        Set<Method> methods = ReflectionUtils.getMethods(target.getClass(), ReflectionUtils.withName(targetMethod.getName()));
        Iterator<Method> iterator = methods.iterator();
        Method method = null;
        while (iterator.hasNext()) {
            method = iterator.next();
        }
        Class<?>[] parameterTypes = method.getParameterTypes();
        try {
            Class<?> aClass = Class.forName(parameterTypes[0].getName());
            Class<String> stringClass = String.class;
            if (stringClass == aClass) {
                result = apiRunable.run(parameter);

        ....