全部产品

泛化调用

在进行 RPC 调用时,应用无需依赖服务提供方的 Jar 包,只需要知道服务的接口名、方法名即可调用 RPC 服务。

泛化接口

public interface GenericService{

/**
   * 泛化调用仅支持方法参数为基本数据类型,
   * 或者方法参数类型在当前应用的 ClassLoader 中存在的情况
   * 
   * @param methodName 调用方法名
   * @param args 调用参数列表
   * @return 调用结果
   * @throws com.alipay.sofa.rpc.core.exception.GenericException 调用异常
   */
Object $invoke(String methodName,String[] argTypes,Object[] args) throws GenericException;

/**
  * 支持参数类型无法在类加载器加载情况的泛化调用,对于非 JDK 类会序列化为 GenericObject
  *
  * @param methodName  调用方法名
  * @param argTypes  参数类型
  * @param args 方法参数,参数类型支持 GenericObject
  * @return result GenericObject 类型
  * @throws com.alipay.sofa.rpc.core.exception.GenericException
  */
Object $genericInvoke(String methodName,String[] argTypes,Object[] args)
throws GenericException;

/**
     * 支持参数类型无法在类加载器加载情况的泛化调用
     *
     * @param methodName 调用方法名
     * @param argTypes   参数类型
     * @param args       方法参数,参数类型支持 GenericObject
     * @param context    GenericContext
     * @return result GenericObject 类型
     * @throws com.alipay.sofa.rpc.core.exception.GenericException
     */
Object $genericInvoke(String methodName,String[] argTypes,Object[] args,
GenericContext context)throws GenericException;

/**
  * 支持参数类型无法在类加载器加载情况的泛化调用,返回结果类型为 T
  *
  * @param methodName  调用方法名
  * @param argTypes  参数类型
  * @param args 方法参数,参数类型支持 GenericObject
  * @return result T 类型
  * @throws com.alipay.sofa.rpc.core.exception.GenericException
  */
<T> T $genericInvoke(String methodName,String[] argTypes,Object[] args,Class<T> clazz) throws GenericException;

/**
     * 支持参数类型无法在类加载器加载情况的泛化调用
     *
     * @param methodName 调用方法名
     * @param argTypes   参数类型
     * @param args       方法参数,参数类型支持 GenericObject
     * @param clazz      返回类型
     * @param context    GenericContext
     * @return result T 类型
     * @throws com.alipay.sofa.rpc.core.exception.GenericException
     */
<T> T $genericInvoke(String methodName,String[] argTypes,Object[] args,Class<T> clazz,GenericContext context)throwsGenericException;

}

$invoke 仅支持方法参数类型在当前应用的 ClassLoader 中存在的情况;$genericInvoke 支持方法参数类型在当前应用的 ClassLoader 中不存在的情况。

使用示例

Spring XML 配置:

<!-- 引用 TR 服务 -->
<sofa:reference interface="com.alipay.sofa.rpc.api.GenericService" id="genericService">
    <sofa:binding.tr>
        <sofa:global-attrs generic-interface="com.alipay.test.SampleService"/>
    </sofa:binding.tr>
</sofa:reference>

Java 代码:

 /**
     * Java Bean
     */
    public class People{
        private String name;
        private int    age;

        // getters and setters
    }


    /**
     * 服务方提供的接口
     */
    interface SampleService{
        String hello(String arg);
        People hello(People people);
    }
 /**
     * 消费方测试类
     */
    public class ConsumerClass{
        GenericService genericService;

        public void do(){
            // 1. $invoke 仅支持方法参数类型在当前应用的 ClassLoader 中存在的情况
            genericService.$invoke("hello",new String[]{String.class.getName()},new Object[]{"I'm an arg"});

            // 2. $genericInvoke 支持方法参数类型在当前应用的 ClassLoader 中不存在的情况。
            // 2.1 构造参数
            GenericObject genericObject =new GenericObject("com.alipay.sofa.rpc.test.generic.bean.People");// 构造函数中指定全路径类名
            genericObject.putField("name","Lilei");// 调用 putField,指定field值
            genericObject.putField("age",15);

            // 2.2 进行调用,不指定返回类型,返回结果类型为 GenericObject
            Object obj = genericService.$genericInvoke("hello",new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"},new Object[]{ genericObject });
            Assert.assertTrue(obj.getClass()==GenericObject.class);

            // 2.3 进行调用,指定返回类型
            People people = genericService.$genericInvoke("hello",new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"},new Object[]{ genericObject },People.class);

            // 3. LDC 架构下的泛化调用使用
            // 3.1 构造 GenericContext 对象
            AlipayGenericContext genericContext =new AlipayGenericContext();
            genericContext.setUid("33");

            // 3.2 进行调用
            People people = genericService.$genericInvoke("hello",new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"},new Object[]{ genericObject },People.class, genericContext);
        }

特殊说明

调用 $genericInvoke(String methodName, String[] argTypes, Object[] args) 接口,会将除以下包以外的其他类序列化为 GenericObject

"com.sun",
"java",
"javax",
"org.ietf",
"org.ogm",
"org.w3c",
"org.xml",
"sunw.io",
"sunw.util"