手写一个轻量级的网关API
【摘要】
以HTTP接口形式的应用,是目前大部分中小型企业最常见的微服务夸语言交互的实现方式
即:定义多个接口,外部调用,经网关解析进行分发,小编遇到的这种情况是,有多个服务,每个服务都需要单独有网关开墙...
以HTTP接口形式的应用,是目前大部分中小型企业最常见的微服务夸语言交互的实现方式
即:定义多个接口,外部调用,经网关解析进行分发,小编遇到的这种情况是,有多个服务,每个服务都需要单独有网关开墙,很是头疼,每上线一个服务都需要网关配置,极其头疼,再次实现一种暴露一个接口,通过参数来实现调用不同的方法的案例,
注意:改方案只适合学习,不适合线上项目
目录
思路分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xpzTUqJE-1663157176960)(http://upload-images.jianshu.io/upload_images/4279695-4b9da3fce59f2cc4?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
实现方案:
-
- 自定义注解 APiMapping
- 自定义ApiGateWayServlet
- 利用 Spring IOC 拆分方法并与 ApiMaping 做绑定由 ApiStore中HashMap维护
注解定义及利用IOC绑定注解与方法
api注解: APIMapping
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface APIMapping {
String value();
RequestMethod method();
}
- 1
- 2
- 3
- 4
- 5
- 6
通过注解对业务方法标记
@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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
利用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);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
重写自定义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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
根据接口绑定获取到执行的方法,利用反射执行
public class ApiRunnable {
private String apiName;
private Method targetMethod;
private String targetName;
private Object target;
private String Method;
- 1
- 2
- 3
- 4
- 5
- 6
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);
....
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
文章来源: springlearn.blog.csdn.net,作者:西魏陶渊明,版权归原作者所有,如需转载,请联系作者。
原文链接:springlearn.blog.csdn.net/article/details/78053401
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)