实操 | 基于 SOFABoot 进行模块化开发

简介: SOFA 中间件是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,包括微服务研发框架,RPC 框架,服务注册中心,分布式定时任务,限流/熔断框架,动态配置推送,分布式链路追踪,Metrics监控度量,分布式高可用消息队列,分布式事务框架,分布式数据库代理层等组件。

SOFA 中间件是蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,包括微服务研发框架,RPC 框架,服务注册中心,分布式定时任务,限流/熔断框架,动态配置推送,分布式链路追踪,Metrics监控度量,分布式高可用消息队列,分布式事务框架,分布式数据库代理层等组件,是在金融场景里锤炼出来的最佳实践。

SOFABoot 是蚂蚁金服中间件团队开源的基于 Spring Boot 的一个开发框架,SOFABoot 从 2.4.0 版本开始支持基于 Spring 上下文隔离的模块化开发能力,SOFABoot 模块除了包括 Java 代码外,还会包含 Spring 配置文件,每个 SOFABoot 模块都是独立的 Spring 上下文。

SOFABoot 的 Github 的地址是:

https://github.com/alipay/sofa-boot

image.png

背景

为了更好的理解 SOFABoot 模块化开发的概念,我们来区分几个常见的模块化形式:

基于代码组织上的模块化:这是最常见的形式,在开发期,将不同功能的代码放在不同 Java 工程下,在编译期被打进不同 jar 包,在运行期,所有 Java 类都在一个 classpath 下且使用同一个 Spring 上下文,没做任何隔离;

基于 Spring 上下文隔离的模块化:使用 Spring 上下文来做不同功能模块的隔离,在开发期和编译期,代码和配置也会分在不同 Java 工程中,但在运行期,不同的 Spring Bean 相互不可见,IoC 只在同一个上下文内部发生,但是所有的 Java 类还是在一个 ClassLoader 下;

基于 ClassLoader 隔离的模块化:借用 ClassLoader 来做隔离,每个模块都有独立的 ClassLoader,模块与模块之间的 classpath 不同,SOFAArk 就是这种模块化的实践方式。

以上三种模块化形式的隔离化程度逐次递进,但模块化就像一把双刃剑,在降低模块间耦合的同时也给模块间交互增加了成本,本文介绍第二种模块化形式 — 基于 Spring 上下文隔离的模块化。

与基于代码组织上的模块化相比,每个 SOFABoot 模块不仅仅包括 Java 代码,还会包含 Spring 配置文件,这种全新的包组织方式大大降低了用户接入成本,用户只需要简单的引入 Jar 包即可,由 SOFABoot 框架负责刷新模块上下文,无需在原来 Spring 配置文件中新增任何 Bean 定义,简化了接入流程,降低了出错几率。

每个 SOFABoot 模块的 Spring 上下文都是隔离的。在 Spring 开发中,保证 Spring BeanId 不冲突是 Spring 运行的基础,这个限制在应用规模较小时很容易解决,只需用户在定义 BeanId 时稍加注意即可。

但是随着系统规模越来越大,一个系统的开发往往涉及多个团队,保证每个业务定义 BeanId 不重复的成本也越来越高。在 SOFABoot 中,每个 SOFABoot 模块使用独立的 Spring 上下文,避免了不同 SOFABoot 模块间 BeanId 冲突,有效降低企业级多模块开发时团队间的沟通成本。

基本原理

在介绍 SOFABoot 模块化开发使用之前,我们简单了解下其背后的实现原理。下图是应用运行时的逻辑视图:

SOFABoot 模块是模块化开发的最小单元,每个 SOFABoot 模块是一个独立的 Spring 上下文,在 SOFABoot 模块中我们可以定义Bean、发布 RPC 服务、连接数据库等等。

由于上下文隔离,模块与模块之间的 Bean 无法通过 @Autowired 依赖注入,我们提供了 JVM Service/Reference 的方式进行模块间通信。

SOFABoot 提供了两种形式的服务发布和引用,用于解决不同级别的模块间调用问题:

JVM 服务发布和引用:解决一个 SOFABoot 应用内部各个 SOFABoot 模块之间的调用问题

RPC 服务发布和引用:解决多个 SOFABoot 应用之间的远程调用问题

Spring Boot 应用在调用 SpringApplication.run 时会创建一个 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。

下面我们来演示如何开发一个简单的 SOFABoot 模块

1 新建工程

DEMO 工程地址:

https://github.com/caojie09/sofaboot-module-demo

运行需要 JDK 6 及以上、 Maven 3.2.5 以上。

首先我们在 IDE 里新建一个普通 Maven 工程,并创建两个普通的 Maven 模块:

service-facade: 定义服务接口

service-provide: 演示新建 SOFABoot 模块并发布 JVM 服务

  1. 定义服务接口
    service-facade 模块包含用于演示 SOFABoot 模块发布与引用服务接口:
public interface SampleService {
    String message();
}
  1. 定义 SOFABoot 模块
    service-provider 是一个 SOFABoot 模块,它会发布一个 JVM 服务供其他模块使用。首先需要为 service-provider 模块增加 sofa-module.properties 文件,将其定义为 SOFABoot 模块,sofa-module.properties 文件放置在 resources 目录:

Module-Name=com.alipay.sofa.service-provider

  1. 发布服务
    SOFABoot 支持三种形式的服务发布,分别是: XML 方式、Annotation 方式以及 API 编码方式,这里演示的是 XML 方式发布服务。

首先增加 SampleServiceImpl 类,实现 SampleService 接口:

public class SampleServiceImpl implements SampleService {
    private String message;

    public String message() {
        return message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

增加 META-INF/spring/service-provide.xml 文件,将 SampleServiceImpl 发布为 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"
       default-autowire="byName">
    <bean id="sampleService" class="com.alipay.sofa.isle.sample.SampleServiceImpl">
        <property name="message" value="Hello, SOFABoot module."/>
    </bean>

    <sofa:service ref="sampleService" interface="com.alipay.sofa.isle.sample.SampleService">
        <sofa:binding.jvm/>
    </sofa:service>
</beans>

到此为止,我们就成功新建了一个 SOFABoot 模块,并在模块中发布了一个 JVM 服务,可以看到,一个 SOFABoot 模块不仅仅包括代码,还包括 Spring 配置文件。

接下来,在 Spring Boot 工程中,快速集成 SOFABoot 的模块化开发能力,并使用刚刚新建的模块发布的服务
Spring Boot 工程集成模块化开发组件

  1. 新建工程
    Demo 工程地址:

https://github.com/caojie09/sofaboot-module-run

在 Spring Boot 官网 https://start.spring.io 新建一个 web 工程,请选择 Spring Boot 版本号为 1.X,目前不支持 Spring Boot 2。修改 maven 项目的配置文件 pom.xml,将

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.14.RELEASE</version>
    <relativePath/>
</parent>

替换为:

<parent>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>sofaboot-dependencies</artifactId>
    <version>2.4.2</version>
</parent>

并添加如下依赖:

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

这样,一个 Spring Boot 工程便集成了 SOFABoot 模块化开发能力。

  1. 添加 SOFABoot 模块
    添加 SOFABoot 模块很简单,只需要把 SOFABoot 模块的坐标加在当前 maven 工程即可,对于这个例子,只需要在启动类模块添加上面创建的 service-provider 模块:
<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>service-provide</artifactId>
    <version>1.0.0</version>
</dependency>

与传统的 JAR 包代码分发方式相比,SOFABoot 模块不仅仅包括代码,还包括 Spring 配置文件,用户在使用 SOFABoot 模块时,只需增加依赖即可。

  1. 引用服务
    为了直观演示,我们在演示工程增加了一个 Rest 接口,在 Rest 接口中引用上文 SOFABoot 模块发布的 JVM 服务。这里演示的是 Annotation 方式引用服务,只需在类的字段上增加 @SofaReference 注解即可:
@RestController
public class HelloController {
    @SofaReference
    private SampleService sampleService;

    @RequestMapping("/hello-sofamodule")
    public String hello() throws IOException {
        return sampleService.message();
    }
}

访问 http://localhost:8080/hello-sofamodule,可以看到 HelloController 成功调用到了 service-provider 发布的服务。

总结

本文主要介绍了使用 SOFABoot 进行上下文隔离的模块化开发,通过两个简单的用例工程,分别介绍了如何开发一个 SOFABoot 模块以及如何在 Spring Boot 快速集成模块化开发能力。每个 SOFABoot 模块都是独立的 Spring 上下文,SOFABoot 模块不仅仅包括代码,还包括 Spring 配置文件,用户在引用 SOFABoot 模块时,只需简单增加依赖即可,由框架负责刷新模块上下文,无需在 Spring 中新增任何 Bean 定义,简化了接入流程,降低了出错几率。

目录
相关文章
|
Java 应用服务中间件 微服务
微服务技术系列教程(12) - SpringBoot -2.0新特性介绍
微服务技术系列教程(12) - SpringBoot -2.0新特性介绍
92 0
|
Java Maven 微服务
搭建springcloud项目——简单明了(一)
本文讲解搭建springcloud项目的方法:操作和eureka-user
7018 1
搭建springcloud项目——简单明了(一)
|
7月前
|
资源调度 监控 前端开发
第七章(原理篇) 微前端技术之依赖管理与版本控制
第七章(原理篇) 微前端技术之依赖管理与版本控制
227 0
|
6月前
|
XML 前端开发 Java
基于Springboot的web后端开发三层架构上手实操
基于Springboot的web后端开发三层架构上手实操
75 0
|
SQL 程序员 Go
Go语言微服务框架 - 7.Gormer-自动生成代码的初体验
作为一名程序员,我们总是希望能有更简单的开发方式来解决重复性的工作问题。在这个小版本中,我将结合自己的工作,来给出一套自动生成代码的完整方案,供大家借鉴。
83 0
|
7月前
|
设计模式 Java 机器人
学习笔记之二《SpringBoot3-核心特性》
学习笔记之二《SpringBoot3-核心特性》
165 0
|
Java 数据库连接 数据库
spring高级源码笔记:深入理解阿里spring源码核心思想及框架应用
Spring 是分层的 full-stack(全栈) 轻量级开源框架,以 IoC 和 AOP 为内核,提供了展现层 SpringMVC 和业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,已经成为使⽤最多的 Java EE 企业应⽤开源框架。
232 0
|
缓存 监控 Java
从零到一构建完整知识体系,阿里最新SpringBoot原理最佳实践真香
Spring Boot不用多说,是咱们Java程序员必须熟练掌握的基本技能。工作上它让配置、代码编写、部署和监控都更简单,面试时互联网企业招聘对于Spring Boot这个系统开发的首选框架也是考察的比较严苛,如果你不是刚入行,只是停留在会用的阶段,那是远远不够的。 虽然Spring Boot易上手,但很多小伙伴也是时不时会跟我反映,Spring Boot技术体系太庞杂了,包含了太多的技术组件,不知道到底该如何高效学习,建立起全面且完整的Spring Boot技术体系和实践技巧,这个时候站在巨人的肩膀上学习就变得非常有必要了,汲取大佬们的学习经验,避免工作面试踩坑,轻松构建Spring Bo
|
JavaScript 测试技术
【Vue 开发实战】实战篇 # 46:如何做好组件的单元测试
【Vue 开发实战】实战篇 # 46:如何做好组件的单元测试
155 0
【Vue 开发实战】实战篇 # 46:如何做好组件的单元测试
|
运维 监控 Java
最近超火的SOFABoot是个什么东西?带你快速入门SOFABoot
最近超火的SOFABoot是个什么东西?带你快速入门SOFABoot
最近超火的SOFABoot是个什么东西?带你快速入门SOFABoot