• 【SOFARPC】SOFA入门实战


    背景

    由于最近交付项目,甲方使用了SOFA这套体系,之前虽然有过一些了解,但是真正实战还是没有那么熟悉,因此搭建一个实战的demo,熟悉一下相关内容。

    SOFA SIMALE DEMO

    项目搭建

    项目目录结构
    在这里插入图片描述
    如上图所示,sofa-common可以定义api接口,sofa-provider作为服务提供者,sofa-consumer为服务消费者。
    代码传送门:https://gitee.com/kevin1992/sofa-demo.git

    公共API

    public interface HelloService {
        String test(String name);
    }
    
    • 1
    • 2
    • 3
    @Path("/rest-api")
    public interface HttpService {
        @Path("/test")
        @GET
        String test();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    需要注意接口定义,如果是bolt,dubbo协议,接口跟普通接口无异,不需要任何处理。
    如果是rest协议,就需要结合JAXRS注解定义接口,JAXRS注解需要单独引jar包。

    服务提供者

    @SofaServiceBean(interfaceType = HelloService.class, bindings = @SofaServiceBinding(bindingType = "bolt"))
    public class HelloServiceImpl implements HelloService {
        @Override
        public String test(String name) {
            return "hello, " + name;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @SofaService(interfaceType = HttpService.class, bindings = {@SofaServiceBinding(bindingType = "rest")})
    @Service
    public class HttpServiceImpl implements HttpService {
        @Override
        public String test() {
            return "success";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    服务调用者

    写一个controller,调用相关服务,使用@SofaReference注解引入即可。

    @RequestMapping("/test")
    @RestController
    public class ConsumerController {
        @SofaReference(interfaceType = HelloService.class, binding = @SofaReferenceBinding(bindingType = "bolt"))
        private HelloService helloService;
    
        @SofaReference(interfaceType = HttpService.class, binding = @SofaReferenceBinding(bindingType = "rest"))
        private HttpService httpService;
    
        @GetMapping("/bolt")
        public String test() {
            return helloService.test("java");
        }
    
        @GetMapping("/rest")
        public String testRest() {
            return httpService.test();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意事项

    注册中心

    本案例使用的zk,所以服务提供者和消费者application.properties都需要增加注册中心的配置

    com.alipay.sofa.rpc.registry.address=zookeeper://127.0.0.1:2181
    
    • 1

    当然,它还支持其他的几种常见注册中心,这里不一一赘述。可以查看官方文档:https://www.sofastack.tech/projects/sofa-rpc/registry-sofa/

    关于注解

    第一种方法
    服务调用者使用@SofaService和Spring的@Service同时使用,否则不会自动注入Spring Bean。
    第二种方法
    直接使用Sofa提供的复合注解@SofaServiceBean,因为这个注解源码可以看到使用到了@Component

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @SofaService
    @Component
    public @interface SofaServiceBean {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    
        @AliasFor(
            annotation = SofaService.class
        )
        Class<?> interfaceType() default void.class;
    
        @AliasFor(
            annotation = SofaService.class
        )
        String uniqueId() default "";
    
        @AliasFor(
            annotation = SofaService.class
        )
        SofaServiceBinding[] bindings() default {@SofaServiceBinding};
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    其他xml和api也都是支持的,具体参考官方文档。

    rest协议

    默认的服务发布端口是8341,服务启动成功就可以浏览器访问
    http://localhost:8341/rest-api/test

    项目启动问题

    由于使用了java17的版本会报错,如下:
    在这里插入图片描述

    Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @69453e37
    
    
    • 1
    • 2

    原因是高版本jdk对jdk8反射使用的限制导致的,只需要在idea启动服务的时候加入一下jvm参数即可:

    --add-opens java.base/java.lang=ALL-UNNAMED
    
    • 1

    idea如图:

    在这里插入图片描述

  • 相关阅读:
    通过Python的speech_recognition库将音频文件转为文字
    解决方案中word中分节符的使用
    飞书-多维文档-计算时间差
    Double 4 VR智能互动系统在法律法庭上的模拟演练教学
    操作系统:线程同步和调度
    C++如何不通过语法调用成员函数
    AutoCAD Electrical 2022—项目特性
    55欧式空间02——正交矩阵、欧氏空间的同构
    DAO 中常见的投票治理方式
    工具类xxxUtil从application.properties中读取参数
  • 原文地址:https://blog.csdn.net/Kevin_King1992/article/details/136612293