服务调用

需要进行模块之间的服务调用时,使用Feign技术封装服务发现、负载均衡等细节,实现本地化形式的调用。

依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

配置

开发者需要在入口类上配置@EnableFeignClients启用Feign的支持。

DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication
@EnableSwagger2
@EnableDiscoveryClient
@EnableFeignClients
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

远程接口定义

在服务调用端,需要根据服务提供者的接口定义声明远程接口。其中name属性对应服务提供者在注册中心的serviceId,path属性对应@RequestMapping配置。

FooClient.java
package com.example.demo.client;

import com.example.demo.dto.FooDto;
import feign.QueryMap;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

@FeignClient(name = "foo-service", path = "/foos")
public interface FooClient {

    @GetMapping("/{id}")
    FooDto findById(@PathVariable("id") Long fooId);

    @GetMapping("/all")
    List<FooDto> findAll(@RequestParam @QueryMap Map parameters);
}

对应的服务端代码:

FooController.java
package com.example.demo.controller;

import com.example.demo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/foos")
public class FooController {

    @Autowired
    private FooService fooService;
    
    @GetMapping("/{id}")
    public FooDto findById(@PathVariable("id") Long id) {
        return fooService.findById(id);
    }
    
    @GetMapping("/all")
    public List<FooDto> findAll(FooQo fooQo) {
        return fooService.findAll(fooQo);
    }
}

可以使用swagger-codegen插件,根据接口自动生成Feign Client。

如果服务端方法定义的HTTP GET接口参数为封装的对象,在调用端需要使用Map<String, Object>作为参数,并且增加@RequestParam@QueryMap注解,分别表示参数出现在HTTP请求行,并且为封装的内容。

远程服务调用

在业务逻辑层中,只需注入远程接口的实例,和本地方法一样进行调用即可。

BarService.java
package com.example.demo.service;

import com.example.demo.client.FooClient;
import com.example.demo.dto.FooDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BarService {

    @Autowired
    private FooClient fooClient;

    public FooDto getFoo(Long fooId) {
        return fooClient.findById(fooId);
    }
}

参考文档

关于OpenFeign技术的更多内容请参考官方文档:https://cloud.spring.io/spring-cloud-static/Finchley.SR1/multi/multi__spring_cloud_openfeign.html

Last updated