全部产品
云市场
云游戏

发布和引用 JVM 服务

更新时间:2020-06-09 16:55:22

本文主要包括下述 2 部分:

XML 方式

XML 的配置路径是在服务发布和引用类所在模块的 resources/META-INF/spring下。默认没有 spring 文件夹,需要新建。新建 XML 文件时,所需的 schema 请从 resources 下默认生成的 XML 中拷贝。

服务发布

操作步骤示例如下:

  1. 配置一个 Bean:
    1. <bean id="sampleService" class="com.alipay.sofa.runtime.test.service.SampleServiceImpl">
  2. 通过 SOFA 提供的 Spring 扩展标签将上面的 Bean 发布成一个 JVM 服务。
    1. <sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService">
    2. <sofa:binding.jvm/>
    3. </sofa:service>

    标签说明

    • interface 指的是需要发布成服务的接口。
    • ref 指向的是需要发布成 JVM 服务的 Bean。

服务引用

操作步骤示例如下:

  1. 使用 Spring 扩展标签引用服务:

    1. <sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService" id="sampleServiceRef">
    2. <sofa:binding.jvm/>
    3. </sofa:reference>

    标签说明

    • interface:是服务的接口,需要和发布服务时配置的 interface 一致。
    • id:上述配置会生成一个 id 为 sampleServiceRef 的 Spring Bean。
    • servicereference 标签还支持 RPC 服务发布,可参考 RPC 服务发布与引用
  2. 将这个 Bean 注入到当前 SOFABoot 模块 Spring 上下文的任意地方。

Annotation 方式

除了通过 XML 方式发布 JVM 服务和引用之外,SOFABoot 还提供了 Annotation 的方式来发布和引用 JVM 服务。

服务发布

使用方式
在实现类上加一个 @SofaService 注解,对于该注解,说明如下:

  • 如果一个服务已经被加上了 @SofaService 的注解,它就不能再用 XML 的方式去发布服务了。两种方式不能混用。
  • @SofaService 的作用是将一个 Bean 发布成一个 JVM 服务。
  • 接口支持
    • 单接口:当被 @SofaService 注解的类只有一个接口的时候,框架会直接采用这个接口作为服务的接口。
    • 多接口:当被 @SofaService 注解的类实现了多个接口时,可以设置 @SofaServiceinterfaceType 字段来指定服务接口。
  • 类注解和方法注解
    • 类注解:在实现类上打上 @SofaService 注解,则在 Spring Boot 使用 Bean Method 创建 Bean 时,会导致 @Bean@SofaService 分散在两处,而且无法对同一个实现类使用不同的 uniqueId。
    • 方法注解:自 SOFABoot 2.6.0 版本起,支持 @SofaService 作用在 Bean Method 之上。

示例
上述说明示例如下:

  • 单接口实现

    1. @SofaService
    2. public class SampleImpl implements SampleInterface {
    3. public void test() {
    4. }
    5. }
  • 多接口实现

    1. @SofaService(interfaceType=SampleInterface.class)
    2. public class SampleImpl implements SampleInterface, Serializable {
    3. public void test() {
    4. }
    5. }
  • 方法注解

    1. @Configuration
    2. public class SampleSofaServiceConfiguration {
    3. @Bean("sampleSofaService")
    4. @SofaService(uniqueId = "service1")
    5. SampleService service() {
    6. return new SampleServiceImpl("");
    7. }
    8. }

服务引用

使用方式
在引用类里,使用 @SofaReference 注解,对于该注解,说明如下:

  • @SofaReference 在不指定服务接口时,会采用被注解字段的类型作为服务接口。
  • 可以通过设定 @SofaReferenceinterfaceType 属性来指定服务接口。
  • 自 SOFABoot 2.6.0 版本起,支持在 Bean Method 参数上使用 @SofaReference 注解引用 JVM 服务。

示例
上述说明示例如下:

  • 单接口实现

    1. public class SampleServiceRef {
    2. @SofaReference
    3. private SampleService sampleService;
    4. }
  • 多接口实现

    1. public class SampleServiceRef {
    2. @SofaReference(interfaceType=SampleService.class)
    3. private SampleService sampleService;
    4. }
  • 方法注解
    1. @Configuration
    2. public class MultiSofaReferenceConfiguration {
    3. @Bean("sampleReference")
    4. TestService service(@Value("$spring.application.name") String appName,
    5. @SofaReference(uniqueId = "service") SampleService service) {
    6. return new TestService(service);
    7. }
    8. }

编程 API 方式

SOFABoot 为 JVM 服务的发布和引用提供了一套编程 API 方式,方便直接在代码中发布和引用 JVM 服务。

服务发布

使用步骤示例如下:

  1. 首先需要实现 ClientFactoryAware 接口获取编程组件 API:

    1. public class ClientFactoryBean implements ClientFactoryAware {
    2. private ClientFactory clientFactory;
    3. @Override
    4. public void setClientFactory(ClientFactory clientFactory) {
    5. this.clientFactory = clientFactory;
    6. }
    7. }
  2. 使用 clientFactory 通过编程 API 方式发布 JVM 服务:

    1. ServiceClient serviceClient = clientFactory.getClient(ServiceClient.class);
    2. ServiceParam serviceParam = new ServiceParam();
    3. serviceParam.setInstance(new SampleServiceImpl());
    4. serviceParam.setInterfaceType(SampleService.class);
    5. serviceClient.service(serviceParam);

    代码说明

    • 通过 clientFactory 获得 ServiceClient 对象。
    • 构造 ServiceParam 对象,其包含发布服务所需参数。
      • 通过 setInstance 方法来设置需要被发布成 JVM 服务的对象
      • 通过 setInterfaceType 来设置服务的接口。
    • 调用 ServiceClientservice 方法,发布一个 JVM 服务。

服务引用

使用步骤示例如下:

  1. 首先需要实现 ClientFactoryAware 接口获取编程组件 API。参见 服务发布
  2. 使用 clientFactory 通过编程 API 方式发布 JVM 服务:

    1. ReferenceClient referenceClient = clientFactory.getClient(ReferenceClient.class);
    2. ReferenceParam<SampleService> referenceParam = new ReferenceParam<SampleService>();
    3. referenceParam.setInterfaceType(SampleService.class);
    4. SampleService proxy = referenceClient.reference(referenceParam);

    代码说明

    • ClientFactory 中获取一个 ReferenceClient
    • 与发布一个服务类似,构造出一个 ReferenceParam
    • 设置好服务的接口。
    • 调用 ReferenceClientreference 方法。
    • 通过动态客户端创建的 Reference 对象是一个非常重的对象,使用时不要频繁创建,自行做好缓存,否则可能存在内存溢出的风险。

uniqueId 配置方式

有些场景,针对一个接口,可能会需要发布两个服务,分别对应到不同的实现。此时,可以通过配置 uniqueId 来区分不同的实现。
下文主要讲述 uniqueId 在下述 3 中方式中的配置:

下文示例:sampleService 有两个 SampleService 的实现,且这两个实现都需要发布成 JVM Service。

在 xml 中配置

配置步骤示例如下:

  1. 服务发布时加入 uniqueId:

    1. <sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService1" unique-id="ss1">
    2. </sofa:service>
    3. <sofa:service interface="com.alipay.sofa.runtime.test.service.SampleService" ref="sampleService2" unique-id="ss2">
    4. </sofa:service>
  2. 引用服务时,通过指定 uniqueId 区分不同服务:

    • 如要使用 sampleService1 的服务,可指定 unique-idss1,例如:
      1. <sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService" id="sampleService" unique-id="ss1">
      2. </sofa:reference>
    • 如要使用 sampleService2 的服务,可指定 unique-idss2,例如:
      1. <sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService" id="sampleService" unique-id="ss2">
      2. </sofa:reference>

在 Annotation 中配置

使用 Annotation 方式发布 JVM 服务和引用时,可以通过设置 @SofaService@SofaReference 的 uniqueId 属性来设置 uniqueId。

在编程 API 中配置

使用编程 API 方式发布或者引用 JVM 服务时,可以通过 ServiceParamReferenceParam 的 setUniqueId 方法来设置 uniqueId。