dubbo接口泛化调用例子

@ApiOperation(value = "dubbo泛化调用工具接口")
    public Result dubboApiTool(
            @ApiParam(value = "interfaceName", defaultValue = "com.shop.api.ShopService") @Param(value = "interfaceName", required = true) String interfaceName,
            @ApiParam(value = "methodName", defaultValue = "loadShopByCode") @Param(value = "methodName", required = true) String methodName,
            @ApiParam(value = "接口入参列表", defaultValue = "[]")
            @Json(value = "methodParams", array = Object.class, defaultValue = "[]") List<Object> methodParams,
            HttpServletRequest request) throws ClassNotFoundException {

        // 校验登录
        Result checkLoginResult = CommonUtil.loginAuthVerify(request);
        if (!checkLoginResult.isSuccess()) {
            log.error("未登录用户无权限执行此操作");
            return checkLoginResult;
        }

        if (!OptimusConfig.getValue("TOOL_API_OPERATORS_MOBILES")
                .contains(((Principal) checkLoginResult.getData()).getUserPhone())) {
            return Result.fail("401", "当前用户无操作权限");
        }

        ApplicationConfig application = new ApplicationConfig();
        application.setName("api-generic-consumer-zjt");

        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(OptimusConfig.getValue("dubbo.registry.address", "zookeeper://stable.zk.scsite.net:2181"));
        application.setRegistry(registry);

        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        // 弱类型接口名
        reference.setInterface(interfaceName);
        // 声明为泛化接口
        reference.setGeneric(true);

        reference.setApplication(application);

        // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
        GenericService genericService = reference.get();

        /**
         * GenericService 这个接口只有一个方法,名为 $invoke,它接受三个参数,分别为方法名、方法参数类型数组和参数值数组;
         * 对于方法参数类型数组 如果是基本类型,如 int 或 long,可以使用 int.class.getName()获取其类型; 如果是基本类型数组,如
         * int[],则可以使用 int[].class.getName(); 如果是 POJO,则直接使用全类名,如
         * com.alibaba.dubbo.samples.generic.api.Params。
         */

        //全部方法
        Method[] methods = Class.forName(interfaceName).getMethods();

        Method method = Arrays.stream(methods).filter(m ->
                methodName.equalsIgnoreCase(m.getName())
                        && methodParams.size()==m.getParameterTypes().length)
                .findFirst().get();

        Class[] params = method.getParameterTypes();

        List<String> paramNameList = Arrays.stream(params).map(p -> p.getName()).collect(Collectors.toList());


        Map map = (Map) genericService.$invoke(methodName,
                paramNameList.toArray(new String[paramNameList.size()]),
                methodParams.toArray(new Object[methodParams.size()]));

        return Result.success(new JSONObject(map).toJSONString());

    }

 

posted on 2019-07-24 15:45  zhaojiatao  阅读(3576)  评论(0编辑  收藏  举报

导航