spring cloud实战之feign

1.环境搭建

增加feign依赖,网上搜索到的都是如下配置:

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
其实这个配置不对,spring boot根本无法启动feign注解,正确的方式如下:
 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
上一节中,使用类似 restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody()这样的语句进行服务间调用并非不可以,只是我们在服务化的过程中,希望跨服务调用能够看起来像本地调用,这也是我理解的Feign的使用场景

*启用

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class EurekaClientApplication {

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

*定义服务,声明feignclient,使得远程调用如同调用本地服务一样,并且可以和eureka完美集成

package hello;

import hello.depends.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * Created by hanruikai on 2018/7/3.
 */


@RestController
@RequestMapping("/api/v1/")
class TestController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private TestService testService;

    @GetMapping("testinvoke")
    public List<ServiceInstance> serviceInstancesByApplicationName() {
        restTemplate.exchange("http://SERVICE-PROVIDER/test",HttpMethod.GET,null,String.class);
        return null;
    }

    @GetMapping("invokedByFeign")
    public List<ServiceInstance> invokeByFeign() {
        testService.helloTest();
        return null;
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
package hello.depends;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by hanruikai on 2018/7/3.
 */
@FeignClient("SERVICE-PROVIDER")
public interface TestService {

    @GetMapping(value="test")
    String helloTest();
}

其中

@FeignClient("SERVICE-PROVIDER")

参数值为调用的服务的名称,此处为eureka中的application name,也就是服务名称

@GetMapping中的value是需要调用的服务的接口,服务提供方代码如下:

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaProviderApplication {

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

@RestController
class ServiceInstanceRestController {


    @GetMapping("/test")
    public void test() {
        System.out.print("invoked successfully");
    }
}

2 如何传递参数

feign client代码修改如下:

package hello.depends;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by hanruikai on 2018/7/3.
 */
@FeignClient("SERVICE-PROVIDER")
public interface TestService {

    @PostMapping(value="test")
    String helloTest(@RequestBody String name);
}
 @GetMapping("invokedByFeign")
    public List<ServiceInstance> invokeByFeign() {
        testService.helloTest("kerry");
        return null;
    }

provider:

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaProviderApplication {

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

@RestController
class ServiceInstanceRestController {


    @PostMapping("/test")
    public void test(@RequestBody String name) {
        System.out.print("invoked successfully"+name);
    }
  }

3 如果没有Eureka,服务名称不存在怎么办

package hello.depends;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Created by hanruikai on 2018/7/3.
 */
@FeignClient(value = "test",url = "http://localhost:8090")
public interface TestService {

    @PostMapping(value="test")
    String helloTest(@RequestBody String name);
}

feignclient注解除了name,还有url,可以指定url进行调用。这样可以把重复的rest调用封装到service里面,用feign进行声明式rest client。




猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/80898058