SOFABoot——基本使用(笔记)

文章目录

  • 一、前言
  • 二、快速开始
    • 2.1 基本搭建
    • 2.2 测试是否成功
    • 2.3 其他部分
      • 日志
      • 测试
      • 异步启动
  • 三、SOFABoot的模块化开发
    • 3.1 基于Spring上下文的隔离
    • 3.2 Root Application Context
    • 3.3 模块并行化启动
    • 3.4 JVM服务与RPC服务的发布与引用
    • 3.5 模块配置
        • Module-Name
        • Require-Module
        • Spring-Parent
        • Module-Profile
    • 3.6 JVM 服务发布与引用实例
      • 3.6.1 facade模块声明接口
      • 3.6.2 provide中实现接口与基本配置
      • 3.6.3 consumer基本配置
      • 3.6.4 BootRun基本配置
      • 3.6.5 XML方式发布与引用
      • 3.6.6 注解方式发布与引用
        • 3.6.6.1 通过XML管理
        • 3.6.6.2 @Bean方式
        • 3.6.6.3 多接口
      • 3.6.7 代码方式发布与引用
  • 参考文档

一、前言

SOFABoot 是蚂蚁金服开源的基于 Spring Boot 的研发框架。

具体可见

  • SOFABoot
  • SOFABoot官方文档

版本关系
在这里插入图片描述

二、快速开始

2.1 基本搭建

依官方文档所言,为顺利从中央仓库拉取 SNAPSHOT 包我们在Maven的setting.xml中加入如下配置:

<profile><id>default</id><activation><activeByDefault>true</activeByDefault></activation><repositories><repository><snapshots><enabled>true</enabled></snapshots><id>maven-snapshot</id><url>https://oss.sonatype.org/content/repositories/snapshots</url></repository></repositories><pluginRepositories><pluginRepository><snapshots><enabled>true</enabled></snapshots><id>maven-snapshot</id><url>https://oss.sonatype.org/content/repositories/snapshots</url></pluginRepository></pluginRepositories>
</profile>

创建Maven项目

以如下依赖为参考

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>test</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><groupId>com.alipay.sofa</groupId><artifactId>sofaboot-dependencies</artifactId><version>2.3.1</version></parent><dependencies><dependency><groupId>com.alipay.sofa</groupId><artifactId>healthcheck-sofa-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include><include>**/*.yml</include></includes></resource></resources></build>
</project>

同SpringBoot一样,完成MainApplication的创建,然后运行

可参考Spring Boot2——基本使用(笔记)

package com.test;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MainApplication {public static void main(String[] args){SpringApplication.run(MainApplication.class,args);}
}

依据滚网,加入如下配置一下yml文件:

server:port: 8080
spring:application:name: testApplication
logging:path: ./logs

2.2 测试是否成功

  • 查询如下网址,SOFABoot 中使用 Maven 插件生成的版本信息汇总
http://localhost:8080/sofaboot/versions
(在SOFABoot 3.x 中调整了 endpoint 路径,sofaboot/versions 更改为 actuator/versions)

点击直接查询(3.x 前)

点击直接查询(3.x 后)

[{"GroupId": "com.alipay.sofa","Doc-Url": "https://github.com/alipay/sofa-boot","ArtifactId": "infra-sofa-boot-starter","Bulit-Time": "2018-04-18T22:19:09+0800","Commit-Time": "2018-04-18T22:07:52+0800","Commit-Id": "466f0e039b250ff7b201dc693eec7fa07eb21ad7","Version": "2.3.1"}
]
  • 查询如下网址,查看应用 Readiness Check 的状况
http://localhost:8080/health/readiness
(在 SOFABoot 3.x 中调整了 endpoint 路径,health/readiness 更改为 actuator/readiness)

点击直接查询(3.x 前)

点击直接查询(3.x 后)

{"status": "UP","sofaBootComponentHealthCheckInfo": {"status": "UP"},"springContextHealthCheckInfo": {"status": "UP"},"DiskSpaceHealthIndicator": {"status": "UP","total": 53685972992,"free": 47562289152,"threshold": 10485760}
}

status: “UP” ,表示应用 Readiness Check 健康的。

  • 使用如下查询,查看应用的运行时健康状态
http://localhost:8080/health
(在 SOFABOOT 3.X 中调整了 endpoint 路径,/health 更改为 /actuator/health)

点击直接查询(3.x 前)

点击直接查询(3.x 后)

2.3 其他部分

日志

日志文件结构如下

./logs
├── health-check
│   ├── sofaboot-common-default.log
│   └── sofaboot-common-error.log
├── infra
│   ├── common-default.log
│   └── common-error.log
└── spring.log

测试

在不使用SOFABoot的类隔离能力时,可以不使用SOFABoot的测试包。即,原来的测试包。
但如果要使用类隔离能力的时候,我们必须使用如下引用。(类隔离能力见后文)

<dependency><groupId>com.alipay.sofa</groupId><artifactId>test-sofa-boot-starter</artifactId>
</dependency>

对应的单元测试注解为:

@SofaBootRunner 
@SofaJUnit4Runner

可参考Spring官网-Test scope dependencies

使用如下

		<dependency><groupId>com.alipay.sofa</groupId><artifactId>test-sofa-boot-starter</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
package com.test;import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class) //SpringJUnit4ClassRunner.class 也可以
@SpringBootTest(classes = MainApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {private static Logger log = LoggerFactory.getLogger(test.class);@Testpublic void UnitTest(){int a = 33;log.info("你好{}",a);}
}

在这里插入图片描述
Spring:SpringRunner 和 SpringJUnit4ClassRunner

异步启动

SOFABoot 在 v2.6.0 开始提供异步初始化 Spring Bean 能力,引入如下 Starter 即可:

<dependency><groupId>com.alipay.sofa</groupId><artifactId>runtime-sofa-boot-starter</artifactId>
</dependency>

三、SOFABoot的模块化开发

官网的文档中,项目分为如下4个模块。官方样例下载地址-sofa-boot-guides

.
│
├── service-facade 
│ 
├── service-provider
│ 
├── service-consumer
│ 
└── sofa-boot-run
  • service-facade: 演示 JVM 服务发布与引用的 API 包
  • service-provider: 演示 XML 方式、Annotation 方式、API 方式发布 JVM 服务
  • service-consumer: 演示 XML 方式、Annotation 方式、API 方式引用 JVM 服务
  • sofa-boot-run: 启动包含 SOFABoot 模块的 SOFA Boot 应用

3.1 基于Spring上下文的隔离

常见的模块化形式:

  • 基于代码组织上的模块化:
    • 在开发期,将不同功能的代码放在不同 Java 工程下,在编译期被打进不同 jar 包
    • 在运行期,所有 Java 类都在一个 classpath 下,没做任何隔离
  • 基于 Spring 上下文隔离的模块化:
    • 借用 Spring 上下文来做不同功能模块的隔离,在开发期和编译期,代码和配置也会分在不同 Java 工程中,但在运行期,不同模块间的 Spring Bean 相互不可见
    • DI(Dependency Injection,依赖注入)只在同一个上下文内部发生,但是所有的 Java 类还是在同一个 ClassLoader 下;
  • 基于 ClassLoader 隔离的模块化:
    • 借用 ClassLoader 来做隔离,每个模块都有独立的 ClassLoader,模块与模块之间的 classpath 不同

SOFABoot 模块化开发属于模块化形式 —— 基于 Spring 上下文隔离的模块化。每个 SOFABoot 模块使用独立的 Spring 上下文,避免不同 SOFABoot 模块间的 BeanId 冲突,有效降低企业级多模块开发时团队间的沟通成本。


取自 蚂蚁金服的业务系统模块化之模块化隔离方案

我们常常见到一个系统中的模块会按照如下的方式进行分层,如下图中的左边部分所示,一个系统就简单地分为 Web 层、Service 层、DAL 层。

当这个系统承载的业务变多了之后,系统可能演化成上图中右边的这种方式。在上图的右边的部分中,一个系统承载了两个业务,一个是 Cashier(收银台),另一个是 Pay(支付),这两个业务可能会有一些依赖的关系,Cashier 需要调用 Pay 提供的能力去做支付。
在这里插入图片描述

但是在这种模块化的方案里面,Spring 的上下文依然是同一个,类也没有任何做隔离,这就意味着,Pay Service 这个模块里面的任何的一个 Bean,都可以被 Cashier Service 这个模块所依赖。极端的情况下,可能会出现下面这种情况:

  • Cashier Service 错误地调用了 Pay Service 中的一个内部的 Bean,造成了两个模块之间的紧耦合。

在这里插入图片描述

SOFA的模块化如下
在这里插入图片描述

可以看到每一个小模块单独有一个Spring上下文.通过这种方式将他们强制分开,而不是同之前一样,由开发者自觉遵守。

在这里插入图片描述

以 SOFABoot 模块为单元的模块化方式为开发者提供了以下功能:

  • 运行时,每个 SOFABoot 模块的 Spring 上下文是隔离的,模块间定义的 Bean 不会相互影响
  • 每个 SOFABoot 模块是功能完备且自包含的,可以很容易在不同的 SOFABoot 应用中进行模块迁移和复用,只需将 SOFABoot 模块整个拷贝过去,调整 Maven 依赖,即可运行。

3.2 Root Application Context

SOFABoot 应用运行时,本身会产生一个 Spring Context,我们把它叫做 Root Application Context,它是每个 SOFABoot 模块创建的 Spring Context 的 Parent。

这样设计的目的是为了保证每个 SOFABoot 模块的 Spring Context 都能发现 Root Application Context 中创建的 Bean,这样当应用新增 Starter 时,不仅 Root Application Context 能够使用 Starter 中新增的 Bean,每个 SOFABoot 模块的 Spring Context 也能使用这些 Bean。

也就是一些全局的Bean。

3.3 模块并行化启动

每个 SOFABoot 模块都是独立的 Spring 上下文,多个 SOFABoot 模块支持并行化启动,与 Spring Boot 的单 Spring 上下文模式相比,模块并行化启动能够加快应用的启动速度。

3.4 JVM服务与RPC服务的发布与引用

上下文隔离后,模块与模块间的 Bean 无法直接注入,模块间需要通过 SOFA 服务进行通信,目前SOFABoot 提供了两种形式的服务发布和引用,用于解决不同级别的模块间调用的问题:

  • JVM 服务发布和引用:解决一个 SOFABoot 应用内部各个 SOFABoot 模块之间的调用问题, JVM 服务发布与引用
  • RPC 服务发布和引用:解决多个 SOFABoot 应用之间的远程调用问题,RPC 服务发布与引用。

3.5 模块配置

S O F A B o o t 模块 = 普通的 J a r 包 + S O F A B o o t 特有的配置 SOFABoot 模块 = 普通的 Jar 包 + SOFABoot 特有的配置 SOFABoot模块=普通的Jar+SOFABoot特有的配置

共有4种配置文件

Module-Name = com.alipay.test.biz.service.impl
Spring-Parent = com.alipay.test.common.dal
Require-Module = com.alipay.test.biz.shared
Module-Profile = dev

Module-Name

Module-Name 是 SOFABoot 模块的名称,也是 SOFABoot 模块的唯一标示符。

在一个 SOFABoot 应用中,一个SOFABoot 模块的 Module-Name 必须和其他的 SOFABoot 模块的 Module-Name 不一样。

需要注意的一点是,一个 SOFABoot 应用运行时的 SOFABoot 模块,不仅仅只包含本应用的模块,还包括依赖了其他应用的 SOFABoot 模块,确定是否唯一的时候需要把这些 SOFABoot 模块也考虑进去。

其实就是配置的服务的实现,通过com.alipay.test.biz.service.impl,就很容易发现,其实就是xxxServiceImpl因为在SOFABoot中,它们被分在了不同的Spring上下文。通过配置文件指定接口的实现。

Require-Module

Require-Module 用于定义模块之间的依赖顺序,值是以逗号分隔的 SOFABoot 模块名列表,比如上面的配置中,就表示本模块依赖于 com.alipay.test.biz.shared 模块。

对于这种依赖关系的处理,SOFABoot 会将 com.alipay.test.biz.shared 模块在本模块之前启动,即com.alipay.test.biz.shared 模块将先启动 Spring 上下文。


一般情况下,是不需要为模块定义 Require-Module 的,只有当模块的 Spring 上下文的启动依赖于另一个模块的 Spring 上下文的启动时,才需要定义 Require-Module。

举一个例子,如果你在 A 模块中发布了一个 SOFA JVM Service。在 B 模块的某一个 Bean 的 init 方法里面,需要使用 SOFA Reference 调用这个 JVM Service。假设 B 模块在 A 模块之前启动了,那么 B 模块的 Bean 就会因为 A 模块的 JVM Service 没有发布而 init 失败,导致 Spring 上下文启动失败。这个时候,我们就可以使用 Require-Module 来强制 A 模块在 B 模块之前启动。

Spring-Parent

在 SOFABoot 应用中,每一个 SOFABoot 模块都是一个独立的 Spring 上下文,并且这些 Spring 上下文之间是相互隔离的。

虽然这样的模块化方式可以带来诸多好处,但是,在某些场景下还是会有一些不便,这个时候,你可以通过 Spring-Parent 来打通两个 SOFABoot 模块的 Spring 上下文。

Spring-Parent 属性可以配置一个模块的名称,比如上面的配置中,就将 com.alipay.test.common.dal 的 Spring 上下文设置为当前模块的 Spring 上下文的父 Spring 上下文。

由于 Spring 的限制,一个模块的 Spring-Parent 只能有一个模块。关于 Spring 的父上下文的作用可以看 Spring 的 BeanFactory 的说明:Interface BeanFactory

Module-Profile

支持 SOFABoot Profile 能力,详情参考- SOFABoot Profile

也就是配置运行环境(dev、test、product),当处于对应的环境时,模块就会启动,或者说激活。

3.6 JVM 服务发布与引用实例

有三种方式,可参考 JVM 服务发布与引用

  • XML 方式
  • Annotation 方式
  • 编程 API 方式

对于同一个服务,不能混用XML与Annotation方式

我们可以依据分类创建如下结构,下图是官方样例中的内容。
在这里插入图片描述

  • boot:启动模块,含有MainApplication与控制层
  • facade:Service接口所在
  • provide:Service方法实现
  • consumer:引用Service,让其可被作为Bean使用

我们另建一个项目。
在这里插入图片描述
在上图pom.xml文件中加入如下代码

	<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>sofaBootTest</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>service-consumer</module><module>service-provider</module><module>sofa-boot-run</module><module>service-facade</module></modules><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><maven.surefire.plugin>2.21.0</maven.surefire.plugin></properties><parent><groupId>com.alipay.sofa</groupId><artifactId>sofaboot-dependencies</artifactId><version>3.2.0</version></parent><dependencyManagement><dependencies><dependency><groupId>com.alipay.sofa</groupId><artifactId>isle-sofa-boot-starter</artifactId><version>3.2.0</version></dependency><dependency><groupId>org.example</groupId><artifactId>service-provider</artifactId><version>${project.version}</version></dependency><dependency><groupId>org.example</groupId><artifactId>service-facade</artifactId><version>${project.version}</version></dependency><dependency><groupId>org.example</groupId><artifactId>service-consumer</artifactId><version>${project.version}</version></dependency><dependency><groupId>org.example</groupId><artifactId>sofa-boot-run</artifactId><version>${project.version}</version></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><profiles><profile><id>jdk8</id><activation><jdk>1.8</jdk></activation><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${maven.surefire.plugin}</version><dependencies><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>6.2</version></dependency></dependencies><configuration><reuseForks>false</reuseForks></configuration></plugin></plugins></build></profile><profile><id>jdk11</id><activation><jdk>11</jdk></activation><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${maven.surefire.plugin}</version><dependencies><dependency><groupId>org.ow2.asm</groupId><artifactId>asm</artifactId><version>6.2</version></dependency></dependencies><configuration><reuseForks>false</reuseForks><argLine>-Djdk.attach.allowAttachSelf --add-opensjava.base/jdk.internal.loader=ALL-UNNAMED</argLine></configuration></plugin></plugins></build></profile></profiles>
</project>

3.6.1 facade模块声明接口

于facade模块中创建一个服务

package com.facadeTest;public interface SampleService {String message();
}

3.6.2 provide中实现接口与基本配置

创建 sofa-module.properties 文件如图

在这里插入图片描述

并在文件中,添加如下配置,为我们模块的命名

Module-Name=com.service-provider

3.6.3 consumer基本配置

同理伪consumer创建一个sofa-module.properties 文件。

Module-Name=com.service-consumer
Require-Module=com.service-provider

在 sofa-module.properties 文件中需要指定 Require-Module,保证 service-provider 模块在 service-consumer 模块之前刷新。

3.6.4 BootRun基本配置

我们在BootRun中创建好SpringBoot的基本架构
在这里插入图片描述
导入如下文件即可:

	 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alipay.sofa</groupId><artifactId>healthcheck-sofa-boot-starter</artifactId></dependency><dependency><groupId>com.alipay.sofa</groupId><artifactId>test-sofa-boot-starter</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alipay.sofa</groupId><artifactId>isle-sofa-boot-starter</artifactId></dependency><dependency><groupId>org.example</groupId><artifactId>service-provider</artifactId></dependency><dependency><groupId>org.example</groupId><artifactId>service-facade</artifactId></dependency><dependency><groupId>org.example</groupId><artifactId>service-consumer</artifactId></dependency></dependencies><build><plugins><!-- http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html --><plugin><groupId>org.springframework.boot</groupId><!-- http://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html --><artifactId>spring-boot-maven-plugin</artifactId><version>1.4.2.RELEASE</version><configuration><!-- executable fat jar --><outputDirectory>../target/boot</outputDirectory><classifier>executable</classifier></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>

另外注意一定要yml或者properties文件配置应用名和日志路径,否则会报错。(可见第二部分)

package com.sofaBootRun;import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.facadeTest.SampleService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest(classes = MainApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class test {@SofaReference(uniqueId = "sampleService")private SampleService sampleJvmService;@SofaReference(uniqueId = "annotationImpl")private SampleService sampleJvmServiceAnnotationImpl;@SofaReference(uniqueId = "serviceClientImpl")private SampleService sampleJvmServiceClientImpl;@Testpublic void test() {Assert.assertEquals("Hello, jvm service xml implementation.", sampleJvmService.message());Assert.assertEquals("Hello, jvm service annotation implementation.",sampleJvmServiceAnnotationImpl.message());Assert.assertEquals("Hello, jvm service service client implementation.",sampleJvmServiceClientImpl.message());}
}

3.6.5 XML方式发布与引用

我们首先于provide模块中实现该接口

package com.providerTest;import com.facadeTest.SampleService;public class SampleServiceImpl implements SampleService {private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}@Overridepublic String message() {System.out.println(message);return message;}
}

在provider服务里面,同Spring,创建如下格式文档 service-provider.xml

在这里插入图片描述

并加入如下内容,将对象放入Bean中

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><bean id="sampleService" class="com.providerTest.SampleServiceImpl"><property name="message" value="Hello, jvm service xml implementation."/></bean><sofa:service ref="sampleService" interface="com.facadeTest.SampleService"><sofa:binding.jvm/></sofa:service>
</beans>

与Spring相同,注意ID和ref里面的一致性。

在consumer里面,同前输入如下内容,然后通过 SOFA 提供的 Spring 扩展标签来将上面的 Bean 发布成一个 SOFA JVM 服务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><sofa:reference id="sampleServiceRef" interface="com.facadeTest.SampleService"><sofa:binding.jvm/></sofa:reference>
</beans>

如果有多个实现,需要配置unique-id如下:

<sofa:reference interface="com.alipay.sofa.runtime.test.service.SampleService" id="sampleService" unique-id="ss2">
</sofa:reference>

3.6.6 注解方式发布与引用

3.6.6.1 通过XML管理

于provider处增加一实现

package com.providerTest;import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.facadeTest.SampleService;@SofaService(uniqueId = "annotationImpl")
public class SampleJvmServiceAnnotationImpl implements SampleService {@Overridepublic String message() {String message = "Hello, jvm service annotation implementation.";System.out.println(message);return message;}
}

将 SampleJvmServiceAnnotationImpl 配置成一个 Spring Bean:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><bean id="sampleJvmServiceAnnotation" class="com.providerTest.SampleJvmServiceAnnotationImpl"/>
</beans>

不在需要于Consumer中配置,使用时只需要

@SofaReference

3.6.6.2 @Bean方式

自 SOFABoot v2.6.0 及 v3.1.0 版本起可使用

通过如下方式,我们可以直接注入Bean中

之前的XML配置也可以使用该方式`

需要注意,不同包中,其SpringBoot注解不会生效
可以用一下方式解决

在Main所在项目将其导入
可以使用@Import注解

@SpringBootApplication
@Import(com.providerTest.SampleSofaServiceConfiguration.class)
public class MainApplication {public static void main(String[] args){SpringApplication.run(MainApplication.class,args);}
}

在Main部分所在项目将其扫入

@SpringBootApplication(scanBasePackageClasses = com.providerTest.SampleSofaServiceConfiguration.class)
public class MainApplication {public static void main(String[] args){SpringApplication.run(MainApplication.class,args);}
}

provider部分

package com.providerTest;import com.alipay.sofa.runtime.api.annotation.SofaService;
import com.facadeTest.SampleService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SampleSofaServiceConfiguration {@Bean("sampleSofaService")@SofaService(uniqueId = "annotationImpl")SampleService service() {return new SampleService() {@Overridepublic String message() {return "Hello, jvm service annotation implementation.";}};}
}

3.6.6.3 多接口

通过如下方式,指定抽象接口

@SofaService(interfaceType=SampleInterface.class)
public class SampleImpl implements SampleInterface, Serializable {public void test() {}
}

3.6.7 代码方式发布与引用

consumer和provider服务需要加入如下包:

		<dependency><groupId>com.alipay.sofa</groupId><artifactId>runtime-sofa-boot-starter</artifactId></dependency>

provider

package com.providerTest;import com.alipay.sofa.runtime.api.aware.ClientFactoryAware;
import com.alipay.sofa.runtime.api.client.ClientFactory;
import com.alipay.sofa.runtime.api.client.ServiceClient;
import com.alipay.sofa.runtime.api.client.param.ServiceParam;
import com.facadeTest.SampleService;public class PublishServiceWithClient implements ClientFactoryAware {private ClientFactory clientFactory;public void init() {ServiceClient serviceClient = clientFactory.getClient(ServiceClient.class);ServiceParam serviceParam = new ServiceParam();serviceParam.setInstance(new SampleServiceImpl("Hello, jvm service service client implementation."));serviceParam.setInterfaceType(SampleService.class);serviceParam.setUniqueId("serviceClientImpl");serviceClient.service(serviceParam);}@Overridepublic void setClientFactory(ClientFactory clientFactory) {this.clientFactory = clientFactory;}
}

放入Spring中

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><bean id="publishServiceWithClient" class="com.providerTest.PublishServiceWithClient" init-method="init"/>
</beans>

consumer

package com.consumerTest;import com.alipay.sofa.runtime.api.aware.ClientFactoryAware;
import com.alipay.sofa.runtime.api.client.ClientFactory;
import com.alipay.sofa.runtime.api.client.ReferenceClient;
import com.alipay.sofa.runtime.api.client.param.ReferenceParam;
import com.facadeTest.SampleService;public class JvmServiceConsumer implements ClientFactoryAware {private ClientFactory    clientFactory;public void init() {ReferenceClient referenceClient = clientFactory.getClient(ReferenceClient.class);ReferenceParam<SampleService> referenceParam = new ReferenceParam<SampleService>();referenceParam.setInterfaceType(SampleService.class);referenceParam.setUniqueId("serviceClientImpl");SampleService sampleJvmServiceClientImpl = referenceClient.reference(referenceParam);sampleJvmServiceClientImpl.message();}public void setClientFactory(ClientFactory clientFactory) {this.clientFactory = clientFactory;}
}

放入Spring中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:sofa="http://sofastack.io/schema/sofaboot"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"default-autowire="byName"><bean id="consumer" class="com.consumerTest.JvmServiceConsumer" init-method="init" />
</beans>

参考文档

SOFABoot
SOFABoot官方文档
蚂蚁金服的业务系统模块化之模块化隔离方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/39137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wsl2安装mysql环境

安装完mysql后通过如下命令启动mysql service mysql start 会显示如下错误&#xff1a; mysql: unrecognized service 实际上上面显示的错误是由于mysql没有启动成功造成的 我们要想办法成功启动mysql才可以 1.通过如下操作就可以跳过密码直接进入mysql环境 2.如果想找到my…

微服务与Nacos概述-5

引入OpenFeign 添加依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>com.alibaba.cloud</groupId>…

“记账”很麻烦,看这场竞赛中的队伍与合合信息是如何解决问题的

在我们日常生活中或多或少都会有记账的情况&#xff0c;以此来对自己的收支和消费习惯进行分析&#xff0c;来帮助自己减少不必要的开支&#xff0c;优化财务决策、合理分配资金&#xff0c;减少财务压力和不必要的浪费。 但记账这个动作本身就是一件比较麻烦的。虽然现阶段有…

数据结构入门 — 时间复杂度、空间复杂度

前言 数据结构_空间复杂度_时间复杂度讲解_常见复杂度对比 本文介绍数据结构中的时间复杂度和空间复杂度 ***文章末尾&#xff0c;博主进行了概要总结&#xff0c;可以直接看总结部分*** 博主博客链接&#xff1a;https://blog.csdn.net/m0_74014525 点点关注&#xff0c;后期…

哈夫曼树(赫夫曼树、最优树)详解

目录 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 什么是哈夫曼树 构建哈夫曼树的过程 哈弗曼树中结点结构 构建哈弗曼树的算法实现 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 路径&#xff1a;…

实验三 图像分割与描述

一、实验目的&#xff1a; &#xff08;1&#xff09;进一步掌握图像处理工具Matlab&#xff0c;熟悉基于Matlab的图像处理函数。 &#xff08;2&#xff09;掌握图像分割方法&#xff0c;熟悉常用图像描述方法。 二、实验原理 1.肤色检测 肤色是人类皮肤重要特征之一&#xff…

7.原 型

7.1原型 【例如】 另外- this指向&#xff1a; 构造函数和原型对象中的this都指向实例化的对象 7.2 constructor属性 每个原型对象里面都有个constructor属性( constructor构造函数) 作用&#xff1a;该属性指向该原型对象的构造函数 使用场景: 如果有多个对象的方法&#…

Springboot 实践(4)swagger-ui 测试controller

前文项目操作&#xff0c;完成了项目的创建、数据源的配置以及数据库DAO程序的生成与配置。此文讲解利用swagger-ui界面&#xff0c;测试生成的数据库DAO程序。目前&#xff0c;项目swagger-ui界面如下&#xff1a; 以”用户管理”为例&#xff0c;简单讲述swagger-ui测试数据库…

无涯教程-Perl - s函数

描述 这不是功能。这是正则表达式替换运算符。根据PATTERN中指定的正则表达式,将数据替换为REPLACE。与m //一样,分隔符由s后的第一个字符定义。 语法 以下是此函数的简单语法- s/PATTERN/REPLACE/返回值 如果失败,此函数返回0,如果成功,则返回替换次数。 例 以下是显示…

【Python机器学习】实验10 支持向量机

文章目录 支持向量机实例1 线性可分的支持向量机1.1 数据读取1.2 准备训练数据1.3 实例化线性支持向量机1.4 可视化分析 实例2 核支持向量机2.1 读取数据集2.2 定义高斯核函数2.3 创建非线性的支持向量机2.4 可视化样本类别 实例3 如何选择最优的C和gamma3.1 读取数据3.2 利用数…

Open3D 最小二乘拟合平面(SVD分解法)

目录 一、算法原理二、代码实现三、结果展示1、点云2、拟合结果四、优秀博客本文由CSDN点云侠原创,原文链接。爬虫网站自重。 一、算法原理 本文实现矩阵奇异值分解方法的最小二乘拟合平面。原理如下: 对于得到的 n n

欧拉函数(质因子分解)

思路&#xff1a; (1)欧拉函数&#xff1a;输入n则输出1~n中与n互质的数的个数。 &#xff08;2&#xff09;计算公式&#xff1a; &#xff08;3&#xff09;证明&#xff1a;&#xff08;容斥原理&#xff09;对于n个数&#xff0c;先分别摘除所有被pi整除的数&#xff0c;…

亿信ABI有什么不同,来看最新DEMO演示

为了给用户营造更好的体验环境&#xff0c;提供更丰富、更完善的服务&#xff0c;亿信华辰旗下核心产品亿信ABI DEMO再次上新啦&#xff01;本次亿信ABI DEMO环境在原有基础上焕新升级&#xff0c;带来了全新的主视觉界面、丰富的行业应用和功能演示DEMO&#xff0c;我们一起来…

季度到季度的组件选择

组件&#xff1a;<template><div class"quarter"><div class"input-wrap" id"closeId" mouseover"handler" click.stop"btn" :style"{color:colorItem}"><i class"el-icon-date"&…

【Java】BF算法(串模式匹配算法)

☀️ 什么是BF算法 BF算法&#xff0c;即暴力算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个与模式串T的第一个字符串进行匹配&#xff0c;若相等&#xff0c;则继续比较S的第二个字符和T的第二个字符&#xff1b;若不相等&#xff0c;则…

【计算机视觉|生成对抗】用深度卷积生成对抗网络进行无监督表示学习(DCGAN)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks 链接&#xff1a;[1511.06434] Unsupervised Representation Learning with Deep Conv…

腾讯云CVM服务器竞价实例是什么?和按量计费有什么区别?

腾讯云服务器CVM计费模式分为包年包月、按量计费和竞价实例&#xff0c;什么是竞价实例&#xff1f;竞价实例和按量付费相类似&#xff0c;优势是价格更划算&#xff0c;缺点是云服务器实例有被自动释放风险&#xff0c;腾讯云服务器网来详细说下什么是竞价实例&#xff1f;以及…

NLP——操作步骤讲义与实践链接

数据集与语料 语料是NLP的生命之源&#xff0c;所有NLP问题都是从语料中学到数据分布的规律语料的分类&#xff1a;单语料&#xff0c;平行语料&#xff0c;复杂结构 语料的例子&#xff1a;Penn Treebank, Daily Dialog, WMT-1x翻译数据集&#xff0c;中文闲聊数据集&#xf…

大数据:Numpy基础应用详解

Numpy基础应用 Numpy 是一个开源的 Python 科学计算库&#xff0c;用于快速处理任意维度的数组。Numpy 支持常见的数组和矩阵操作&#xff0c;对于同样的数值计算任务&#xff0c;使用 NumPy 不仅代码要简洁的多&#xff0c;而且 NumPy 的性能远远优于原生 Python&#xff0c;…

mysql-5.5.62-win32安装与使用

1.为啥是这个版本而不是当前最新的8.0&#xff1f; 因为我要用32位。目前mysql支持win32的版本最新只到5.7.33。 首先&#xff0c;到官网MySQL :: MySQL Downloads 然后选 选一个自己喜欢的版本就好。我这里是如标题版本。下载32位的zip。然后回来解压。 完了创建系统环境变…