SOFARPC services can be published and referenced using annotations, XML configurations, or programming APIs.
Using annotations
The SOFABoot environment supports two types of annotations:
Single-protocol annotations:
@SofaServiceand@SofaReference.Multi-protocol annotations:
@SofaServiceBindingand@SofaReferenceBinding.
Publishing a service
To publish an RPC service, add the @SofaService annotation to the bean and specify the interface and protocol type.
@SofaService(interfaceType =AnnotationService.class, bindings ={@SofaServiceBinding(bindingType ="bolt")})
@Component
public class AnnotationServiceImpl implements AnnotationService{
@Override
public String sayAnnotation(String helloAnno){
return helloAnno;
}
}Referencing a service
You can reference a remote service from a Bean by adding the Reference annotation to a property or method. The Bolt, Dubbo, and REST protocols are supported.
@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;
}
}Using XML configuration
The XML configuration uses the following main tags:
sofa:service: Publishes a service.sofa:reference: References a service.sofa:binding: Specifies the protocol for publishing or referencing a service.
For a complete XML configuration example, see the sample project.
Service publishing examples
Single-protocol publishing
<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>Multi-protocol publishing
<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>
Service referencing examples
Referencing with the Bolt protocol
<sofa:reference id="personReferenceBolt" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.bolt/> </sofa:reference>Referencing with the REST protocol
<sofa:reference id="personReferenceRest" interface="com.alipay.sofa.boot.examples.demo.rpc.bean.PersonService"> <sofa:binding.rest/> </sofa:reference>
Using programming APIs
SOFA provides a unified way to obtain programming APIs for its components through the ClientFactory class. This class lets you store and retrieve the specific API for each component.
Prerequisites
Before using SOFA component programming APIs, add the following dependency to your module:
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-enterprise-sofa-boot-starter</artifactId>
</dependency>Configuration methods
SOFA provides two ways to obtain the ClientFactory:
Implement the ClientFactoryAware interface
The following code provides an example:
public class ClientFactoryBean implements ClientFactoryAware{ private ClientFactory clientFactory; @Override public void setClientFactory(ClientFactory clientFactory){ this.clientFactory = clientFactory; } public ClientFactory getClientFactory(){ return clientFactory; } }Then, configure the preceding
ClientFactoryBeanas a Spring Bean.<bean id="clientFactoryBean" class="com.alipay.test.ClientFactoryBean"/>After you complete these steps, the
ClientFactoryBeancan obtain and use theclientFactoryobject.Use the @SofaClientFactory annotation
The following code provides an example:
public class ClientAnnotatedBean{ @SofaClientFactory private ClientFactory clientFactory; public ClientFactory getClientFactory(){ return clientFactory; } }Add the
@SofaClientFactoryannotation to theClientFactoryfield. Then, configureClientAnnotatedBeanas a Spring Bean.<bean id="clientAnnotatedBean" class="com.alipay.test.ClientAnnotatedBean"/>After you complete these steps, the SOFA framework automatically injects the
ClientFactoryinstance into the field with the@SofaClientFactoryannotation.The preceding operations only obtain the
ClientFactoryobject. To obtain a specific client, such asServiceFactory, call thegetClientmethod ofClientFactory. SOFA enhanced the@SofaClientFactoryannotation to allow you to obtain a specific client directly. The following code provides an example:public class ClientAnnotatedBean{ @SofaClientFactory private ServiceClient serviceClient; public ServiceClient getServiceClient(){ return serviceClient; } }When you use
@SofaClientFactorydirectly on a specific client object, the annotation injects the corresponding client object into the annotated field. In the preceding example,@SofaClientFactoryis used on the field of theServiceClienttype. The SOFA framework injects theServiceClientobject directly into this field. You can obtain any object that exists inClientFactoryin this way.
Programming API examples
You can publish and subscribe to services statically by configuring Spring Beans in XML at application startup. You can also do this dynamically using programming APIs at runtime.
Publishing a Bolt service
ServiceClient serviceClient = clientFactory.getClient(ServiceClient.class);
ServiceParam serviceParam = new ServiceParam();
serviceParam.setInstance(sampleService);
serviceParam.setInterfaceType(SampleService.class);
serviceParam.setUniqueId(uniqueId);
TrBindingParam trBinding = new TrBindingParam();
// Corresponds to the global-attrs tag.
trBinding.setClientTimeout(5000);
serviceParam.addBindingParam(trBinding);
serviceClient.service(serviceParam);Referencing a Bolt service
ReferenceClient referenceClient = clientFactory.getClient(ReferenceClient.class);
ReferenceParam<SampleService> referenceParam = new ReferenceParam<SampleService>();
referenceParam.setInterfaceType(SampleService.class);
referenceParam.setUniqueId(uniqueId);
TrBindingParam trBinding = new TrBindingParam();
// Corresponds to the global-attrs tag.
trBinding.setClientTimeout(8000);
// Corresponds to the method tag.
TrBindingMethodInfo trMethodInfo = new TrBindingMethodInfo();
trMethodInfo.setName("helloMethod");
trMethodInfo.setType("callback");
// The object must implement the com.alipay.sofa.rpc.api.callback.SofaResponseCallback interface.
trMethodInfo.setCallbackHandler(callbackHandler);
trBinding.addMethodInfo(trMethodInfo);
referenceParam.setBindingParam(trBinding);
SampleService proxy = referenceClient.reference(referenceParam);The object returned when you create a SOFA Reference with a dynamic client is resource-intensive. To avoid memory overflow, do not create this object frequently. Instead, cache the object. For backward compatibility, the programming API class names use the TR naming convention, but the classes use the Bolt protocol.