本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
SOFARPC 的服务发布和引用方式包括使用注解方式、使用 XML 配置方式和使用编程 API 方式。
使用注解方式
SOFABoot 环境支持使用注解方式,包括以下两种:
单协议注解:
@SofaService
和@SofaReference
.多协议注解:增加注解
@SofaServiceBinding
和@SofaReferenceBinding
。
服务发布
如果要发布一个 RPC 服务,只需要在 Bean 上面打上 @SofaService
注解,指定接口和协议类型即可。
@SofaService(interfaceType =AnnotationService.class, bindings ={@SofaServiceBinding(bindingType ="bolt")})
@Component
public class AnnotationServiceImpl implements AnnotationService{
@Override
public String sayAnnotation(String helloAnno){
return helloAnno;
}
}
服务引用
对于需要引用远程服务的 Bean,只需要在属性或者方法上打上 Reference
的注解即可,支持 Bolt、Dubbo、REST 协议。
@Component
public class AnnotationClientImpl{
@SofaReference(interfaceType =AnnotationService.class, binding =@SofaReferenceBinding(bindingType ="bolt"))
private AnnotationService annotationService;
public String sayClientAnnotation(String clientAnno){
String result = annotationService.sayAnnotation(clientAnno);
return result;
}
}
使用 XML 配置
XML 配置中主要标签含义如下:
sofa:service
:表示发布服务。sofa:reference
:表示引用服务。sofa:binding
:表示服务发布或引用的协议。
XML 配置完整示例,请参见 示例工程。
服务发布示例
单协议发布
<bean id="personServiceImpl" class="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonServiceImpl"/> <sofa:service ref="personServiceImpl" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.bolt/> </sofa:service>
多协议发布
<sofa:service ref="personServiceImpl" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.bolt/> <sofa:binding.rest/> <sofa:binding.dubbo/> </sofa:service>
服务引用示例
Bolt 协议引用
<sofa:reference id="personReferenceBolt" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.bolt/> </sofa:reference>
REST 协议引用
<sofa:reference id="personReferenceRest" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.rest/> </sofa:reference>
使用编程 API
SOFA 提供一套机制去存放各种组件的编程 API,并提供一套统一的方法,让您可以获取到这些 API。组件编程 API 的存放与获取均通过 SOFA 的 ClientFactory 类进行,通过这个 ClientFactory 类,可以获取到对应组件的编程 API。
前提条件
使用 SOFA 组件编程相关的 API,请确保使用的模块里面已经添加了如下的依赖:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-enterprise-sofa-boot-starter</artifactId>
</dependency>
配置方式
SOFA 提供两种方式获取 ClientFactory
:
实现 ClientFactoryAware 接口
代码示例如下:
public class ClientFactoryBean implements ClientFactoryAware{ private ClientFactory clientFactory; @Override public void setClientFactory(ClientFactory clientFactory){ this.clientFactory = clientFactory; } public ClientFactory getClientFactory(){ return clientFactory; } }
然后,将上面的
ClientFactoryBean
配置成一个 Spring Bean。<bean id="clientFactoryBean" class="com.alipay.test.ClientFactoryBean"/>
完成后,
ClientFactoryBean
就可以获取到clientFactory
对象来使用了。使用 @SofaClientFactory 注解
代码示例如下:
public class ClientAnnotatedBean{ @SofaClientFactory private ClientFactory clientFactory; public ClientFactory getClientFactory(){ return clientFactory; } }
您需要在
ClientFactory
字段上加上@SofaClientFactory
的注解,然后将ClientAnnotatedBean
配置成一个 Spring Bean 。<bean id="clientAnnotatedBean" class="com.alipay.test.ClientAnnotatedBean"/>
完成后,SOFA 框架就会自动将
ClientFactory
的实例注入到被@SofaClientFactory
注解的字段上。以上操作只是获取到
ClientFactory
这个对象,如果要获取特定的客户端(如ServiceFactory
),您还需调用ClientFactory
的getClient
方法。SOFA 对@SofaClientFactory
的注解进行了增强,可以直接通过@SofaClientFactory
来获取具体的 Client,代码示例如下:public class ClientAnnotatedBean{ @SofaClientFactory private ServiceClient serviceClient; public ServiceClient getServiceClient(){ return serviceClient; } }
当
@SofaClientFactory
直接使用在具体的 Client 对象上时,此注解可以直接将对应的 Client 对象注入到被注解的字段上。在上述例子中,@SofaClientFactory
是直接注解在类型为ServiceClient
的字段上,SOFA 框架会直接将ServiceClient
对象注入到这个字段上。所有在ClientFactory
中存在的对象,都可以通过此种方式来获得。
编程 API 示例
服务的发布与订阅不仅可以通过在 XML 中配置 Spring Bean 的方式在应用启动期静态加载,也可以采用编程 API 的方式在应用运行期动态执行,用法如下:
Bolt 服务发布
ServiceClient serviceClient = clientFactory.getClient(ServiceClient.class);
ServiceParam serviceParam = new ServiceParam();
serviceParam.setInstance(sampleService);
serviceParam.setInterfaceType(SampleService.class);
serviceParam.setUniqueId(uniqueId);
TrBindingParam trBinding = new TrBindingParam();
// 对应 global-attrs 标签。
trBinding.setClientTimeout(5000);
serviceParam.addBindingParam(trBinding);
serviceClient.service(serviceParam);
Bolt 服务引用
ReferenceClient referenceClient = clientFactory.getClient(ReferenceClient.class);
ReferenceParam<SampleService> referenceParam = new ReferenceParam<SampleService>();
referenceParam.setInterfaceType(SampleService.class);
referenceParam.setUniqueId(uniqueId);
TrBindingParam trBinding = new TrBindingParam();
// 对应 global-attrs 标签。
trBinding.setClientTimeout(8000);
// 对应 method 标签。
TrBindingMethodInfo trMethodInfo = new TrBindingMethodInfo();
trMethodInfo.setName("helloMethod");
trMethodInfo.setType("callback");
// 对象必须实现 com.alipay.sofa.rpc.api.callback.SofaResponseCallback 接口。
trMethodInfo.setCallbackHandler(callbackHandler);
trBinding.addMethodInfo(trMethodInfo);
referenceParam.setBindingParam(trBinding);
SampleService proxy = referenceClient.reference(referenceParam);
通过动态客户端创建 SOFA Reference 返回的对象是一个非常重要的对象,在使用的时候不要频繁创建,自行做好缓存,否则可能存在内存溢出的风险。 因为编程 API 的类不能轻易变化,类名为了兼容以前的用法,保持 TR 写法,但实际其中走的是 Bolt 协议。