手写一个轻量级的网关API

举报
西魏陶渊明 发表于 2022/09/25 01:50:18 2022/09/25
【摘要】 以HTTP接口形式的应用,是目前大部分中小型企业最常见的微服务夸语言交互的实现方式 即:定义多个接口,外部调用,经网关解析进行分发,小编遇到的这种情况是,有多个服务,每个服务都需要单独有网关开墙,很是头疼,每上线一个服务都需要网关配置,极其头疼,再次实现一种暴露一个接口,通过参数来实现调用不同的方法的案例, 注意:改方案...

以HTTP接口形式的应用,是目前大部分中小型企业最常见的微服务夸语言交互的实现方式

即:定义多个接口,外部调用,经网关解析进行分发,小编遇到的这种情况是,有多个服务,每个服务都需要单独有网关开墙,很是头疼,每上线一个服务都需要网关配置,极其头疼,再次实现一种暴露一个接口,通过参数来实现调用不同的方法的案例,

注意:改方案只适合学习,不适合线上项目

GITHUB项目地址

目录

思路分析

4279695-4b9da3fce59f2cc4
流程图

实现方案:

    1. 自定义注解 APiMapping
    2. 自定义ApiGateWayServlet
    3. 利用 Spring IOC 拆分方法并与 ApiMaping 做绑定由 ApiStore中HashMap维护

注解定义及利用IOC绑定注解与方法

api注解: APIMapping


  
  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.METHOD)
  3. public @interface APIMapping {
  4. String value();
  5. RequestMethod method();
  6. }

通过注解对业务方法标记


  
  1. @APIMapping(value = "biz.api.order",method = RequestMethod.GET)
  2. public OrderInfo getOrderInfo(String orderId) {
  3. OrderInfo orderInfo = OrderInfo.builder().id(orderId).name("测试订单").price(12.2).build();
  4. return orderInfo;
  5. }
  6. @APIMapping(value = "biz.api.order2",method = RequestMethod.POST)
  7. public OrderInfo getOrderDo(OrderInfo orderInfo){
  8. return orderInfo;
  9. }

利用Spring 上下文对标记的方法进行绑定
初始化时候,扫描APIMapping接口


  
  1. String[] names = applicationContext.getBeanDefinitionNames();
  2. Class<?> type;
  3. for (String name : names) {
  4. type = applicationContext.getType(name);
  5. for (Method method : type.getDeclaredMethods()) {
  6. APIMapping apiMapping = method.getDeclaredAnnotation(APIMapping.class);
  7. if (apiMapping!=null){
  8. addApiItem(apiMapping,name,method);
  9. }
  10. }
  11. }

重写自定义Servlet方法中的POST和GET


  
  1. public class ApiGateWayServlet extends HttpServlet {
  2. private ApplicationContext applicationContext;
  3. private ApiGateWayHandler apiGateWayHandler;
  4. @Override
  5. public void init() throws ServletException {
  6. super.init();
  7. applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
  8. apiGateWayHandler = applicationContext.getBean(ApiGateWayHandler.class);
  9. }
  10. @Override
  11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  12. apiGateWayHandler.handle(req,resp);
  13. }
  14. @Override
  15. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  16. apiGateWayHandler.handle(req,resp);
  17. }
  18. }

根据接口绑定获取到执行的方法,利用反射执行


  
  1. public class ApiRunnable {
  2. private String apiName;
  3. private Method targetMethod;
  4. private String targetName;
  5. private Object target;
  6. private String Method;

  
  1. Object result = null;
  2. Object target = apiRunable.getTarget();
  3. Method targetMethod = apiRunable.getTargetMethod();
  4. Set<Method> methods = ReflectionUtils.getMethods(target.getClass(), ReflectionUtils.withName(targetMethod.getName()));
  5. Iterator<Method> iterator = methods.iterator();
  6. Method method = null;
  7. while (iterator.hasNext()) {
  8. method = iterator.next();
  9. }
  10. Class<?>[] parameterTypes = method.getParameterTypes();
  11. try {
  12. Class<?> aClass = Class.forName(parameterTypes[0].getName());
  13. Class<String> stringClass = String.class;
  14. if (stringClass == aClass) {
  15. result = apiRunable.run(parameter);
  16. ....

文章来源: springlearn.blog.csdn.net,作者:西魏陶渊明,版权归原作者所有,如需转载,请联系作者。

原文链接:springlearn.blog.csdn.net/article/details/102425339

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。