本文主要介绍如何进行发布和引用JVM服务,包括下述 2 部分:
发布和引用 JVM 服务的 3 种方式。包括:
XML 方式
XML 的配置路径是在服务发布和引用类所在模块的 resources/META-INF/spring
下。默认没有 spring 文件夹,需要新建。新建 XML 文件时,所需的 schema 请从 resources 下默认生成的 XML 中拷贝。
服务发布
操作步骤示例如下:
配置一个 Bean:
<bean id="sampleService" class="com.alipay.sofa.runtime.test.service.SampleServiceImpl">
通过 SOFA 提供的 Spring 扩展标签将上面的 Bean 发布成一个 JVM 服务。
<sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService"> <sofa:binding.jvm/> </sofa:service>
说明interface 指的是需要发布成服务的接口。
ref 指向的是需要发布成 JVM 服务的 Bean。
服务引用
操作步骤示例如下:
使用 Spring 扩展标签引用服务:
<sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService" id="sampleServiceRef"> <sofa:binding.jvm/> </sofa:reference>
说明interface:是服务的接口,需要和发布服务时配置的 interface 一致。
id:上述配置会生成一个 id 为 sampleServiceRef 的 Spring Bean。
service 与 reference 标签还支持 RPC 服务发布,可参考 RPC 服务发布与引用。
将这个 Bean 注入到当前 SOFABoot 模块 Spring 上下文的任意地方。
Annotation 方式
除了通过 XML 方式发布 JVM 服务和引用之外,SOFABoot 还提供了 Annotation 的方式来发布和引用 JVM 服务。
服务发布
使用方式在实现类上加一个 @SofaService
注解,对于该注解,说明如下:
如果一个服务已经被加上了
@SofaService
的注解,它就不能再用 XML 的方式去发布服务了。两种方式不能混用。@SofaService
的作用是将一个 Bean 发布成一个 JVM 服务。接口支持
单接口:当被
@SofaService
注解的类只有一个接口的时候,框架会直接采用这个接口作为服务的接口。多接口:当被
@SofaService
注解的类实现了多个接口时,可以设置@SofaService
的interfaceType
字段来指定服务接口。
类注解和方法注解
类注解:在实现类上打上
@SofaService
注解,则在 Spring Boot 使用 Bean Method 创建 Bean 时,会导致@Bean
和@SofaService
分散在两处,而且无法对同一个实现类使用不同的 uniqueId。方法注解:自 SOFABoot 2.6.0 版本起,支持
@SofaService
作用在 Bean Method 之上。
示例上述说明示例如下:
单接口实现
@SofaService public class SampleImpl implements SampleInterface{ public void test(){ } }
多接口实现
@SofaService(interfaceType=SampleInterface.class) public class SampleImpl implements SampleInterface,Serializable{ public void test(){ } }
方法注解
@Configuration public class SampleSofaServiceConfiguration{ @Bean("sampleSofaService") @SofaService(uniqueId ="service1") SampleService service(){ return new SampleServiceImpl(""); } }
服务引用
使用方式在引用类里,使用 @SofaReference
注解,对于该注解,说明如下:
@SofaReference
在不指定服务接口时,会采用被注解字段的类型作为服务接口。可以通过设定
@SofaReference
的interfaceType
属性来指定服务接口。自 SOFABoot 2.6.0 版本起,支持在 Bean Method 参数上使用
@SofaReference
注解引用 JVM 服务。
示例上述说明示例如下:
单接口实现
public class SampleServiceRef{ @SofaReference private SampleService sampleService; }
多接口实现
public class SampleServiceRef{ @SofaReference(interfaceType=SampleService.class) private SampleService sampleService; }
方法注解
@Configuration public class MultiSofaReferenceConfiguration { @Bean("sampleReference") TestService service(@Value("$spring.application.name") String appName, @SofaReference(uniqueId = "service") SampleService service) { return new TestService(service); } }
编程 API 方式
SOFABoot 为 JVM 服务的发布和引用提供了一套编程 API 方式,方便直接在代码中发布和引用 JVM 服务。
服务发布
使用步骤示例如下:
首先需要实现
ClientFactoryAware
接口获取编程组件 API:public class ClientFactoryBean implements ClientFactoryAware { private ClientFactory clientFactory; @Override public void setClientFactory(ClientFactory clientFactory) { this.clientFactory = clientFactory; } }
使用
clientFactory
通过编程 API 方式发布 JVM 服务:ServiceClient serviceClient = clientFactory.getClient(ServiceClient.class); ServiceParam serviceParam =new ServiceParam(); serviceParam.setInstance(new SampleServiceImpl()); serviceParam.setInterfaceType(SampleService.class); serviceClient.service(serviceParam);
代码说明
通过
clientFactory
获得ServiceClient
对象。构造
ServiceParam
对象,其包含发布服务所需参数。通过
setInstance
方法来设置需要被发布成 JVM 服务的对象通过
setInterfaceType
来设置服务的接口。
调用
ServiceClient
的service
方法,发布一个 JVM 服务。
服务引用
使用步骤示例如下:
首先需要实现
ClientFactoryAware
接口获取编程组件 API。参见 服务发布。使用
clientFactory
通过编程 API 方式发布 JVM 服务:ReferenceClient referenceClient = clientFactory.getClient(ReferenceClient.class); ReferenceParam<SampleService> referenceParam =new ReferenceParam<SampleService>(); referenceParam.setInterfaceType(SampleService.class); SampleService proxy = referenceClient.reference(referenceParam);
代码说明
从
ClientFactory
中获取一个ReferenceClient
。与发布一个服务类似,构造出一个
ReferenceParam
。设置好服务的接口。
调用
ReferenceClient
的reference
方法。通过动态客户端创建的
Reference
对象是一个非常重的对象,使用时不要频繁创建,自行做好缓存,否则可能存在内存溢出的风险。
uniqueId 配置方式
有些场景,针对一个接口,可能会需要发布两个服务,分别对应到不同的实现。此时,可以通过配置 uniqueId 来区分不同的实现。下文主要讲述 uniqueId 在下述 3 中方式中的配置:
下文示例:sampleService
有两个 SampleService
的实现,且这两个实现都需要发布成 JVM Service。
在 xml 中配置
配置步骤示例如下:
服务发布时加入 uniqueId:
<sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService1"unique-id="ss1"> </sofa:service> <sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService2"unique-id="ss2"> </sofa:service>
引用服务时,通过指定 uniqueId 区分不同服务:
如要使用
sampleService1
的服务,可指定unique-id
为ss1
,例如:<sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService"id="sampleService"unique-id="ss1"> </sofa:reference>
如要使用
sampleService2
的服务,可指定unique-id
为ss2
,例如:<sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService"id="sampleService"unique-id="ss2"> </sofa:reference>
在 Annotation 中配置
使用 Annotation 方式发布 JVM 服务和引用时,可以通过设置 @SofaService
和 @SofaReference
的 uniqueId 属性来设置 uniqueId。
在编程 API 中配置
使用编程 API 方式发布或者引用 JVM 服务时,可以通过 ServiceParam
和 ReferenceParam
的 setUniqueId 方法来设置 uniqueId。