easyopen原理解析——不到100行代码实现一个最精简的easyopen

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/thc1987/article/details/82968242

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就是在此基础上逐渐完善起来的。

原文 

https://blog.csdn.net/thc1987/article/details/82968242

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » easyopen原理解析——不到100行代码实现一个最精简的easyopen

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址