Feign从http调用改成基于dubbo协议调用

时间:2025-03-05 12:07:08

说明

把已经有的feign接口直接改成通过dubbo协议直接调用

Dubbo Spring Cloud 提供了方案,即 @DubboTransported 注解,支持在类,方法,属性上使用。能够帮助服务消费端的 Spring Cloud Open Feign 接口以及 @LoadBalanced RestTemplate Bean 底层走 Dubbo 调用(可切换 Dubbo 支持的协议),而服务提供方则只需在原有 @RestController 类上追加 Dubbo @Servce 注解(需要抽取接口)即可,换言之,在不调整 Feign 接口以及 RestTemplate URL 的前提下,实现无缝迁移。

代码案例

代码来自 图灵学院, 我自己学完,做了个作业,然后给老师的代码整理了一下,加了个注释啥的.

代码地址和使用

/zjj19941/ZJJ_Dubbo/tree/master/spring-cloud-alibaba-dubbo-feign

1.执行sql脚本
2.准备nacos服务端
3.修改配置文件地址
4.启动项目,先启动pringCloudDubboProviderUserFeignApplication , 再启动SpringCloudDubboConsumerUserFeignApplication
执行调用方法
localhost:8080/user/list 这个是http调用
localhost:8080/user/list2 这个是dubbo调用
localhost:8080/user/list3 这个是RestTemplate基于dubbo协议调用

修改服务提供者

@DubboService
@Slf4j
@RestController
@RequestMapping("/user")
public class UserServiceImpl implements UserService {
 
   @Autowired
   private UserMapper userMapper;
 
   @Override
   @RequestMapping("/list")
   public List<User> list() {
      log.info("查询user列表");
      return userMapper.list();
   }
 
   @Override
   @RequestMapping("/getById/{id}")
   public User getById(@PathVariable("id") Integer id) {
      return userMapper.getById(id);
   }
}

服务消费端引入依赖

<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<dependency>
    <groupId></groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
 
<dependency>
    <groupId></groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
 
<dependency>
    <groupId></groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

feign的实现,启动类上添加@EnableFeignClients

@SpringBootApplication
@EnableFeignClients
public class SpringCloudDubboConsumerUserFeignApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudDubboConsumerUserFeignApplication.class, args);
    }
 
}

feign接口添加 @DubboTransported 注解

@FeignClient(value = "spring-cloud-dubbo-provider-user-feign",path = "/user")
@DubboTransported(protocol = "dubbo")
public interface UserDubboFeignService {
 
    @RequestMapping("/list")
    public List<User> list();
 
    @RequestMapping("/getById/{id}")
    public User getById(@PathVariable("id") Integer id);
}
 
@FeignClient(value = "spring-cloud-dubbo-provider-user-feign",path = "/user")
public interface UserFeignService {
 
    @RequestMapping("/list")
    public List<User> list();
 
 
    @RequestMapping("/getById/{id}")
    public User getById(@PathVariable("id") Integer id);
}
 

调用对象添加 @DubboTransported 注解

@RestController
@RequestMapping("/user")
public class UserConstroller {

    @DubboReference
    private UserService userService;

    @RequestMapping("/info/{id}")
    public User info(@PathVariable("id") Integer id) {
        return userService.getById(id);
    }

    @Autowired
    //@DubboTransported(protocol = "dubbo") //思考dubbo协议是否生效?  Spring  单例模式   不生效
    private UserFeignService userFeignService;

    /**
     * feign调用
     * localhost:8080/user/list
     */
    @RequestMapping("/list")
    public List<User> list() {
        return userFeignService.list();
    }

    @Autowired
    private UserDubboFeignService userDubboFeignService;

    /**
     * dubbo调用
     * localhost:8080/user/list2
     */
    @RequestMapping("/list2")
    public List<User> list2() {

        return userDubboFeignService.list();
    }

    @Autowired
    private RestTemplate restTemplate;

    @Bean
    @LoadBalanced
    @DubboTransported
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * dubbo通过RestTemplate调用
     * localhost:8080/user/list3
     */
    @RequestMapping("/list3")
    public List<User> list3() {
        String url = "http://spring-cloud-dubbo-provider-user-feign/user/list";
        return restTemplate.getForObject(url, List.class);
    }

}