天天看点

spring cloud : 简化远程调用 (声明式远程调用Feign)

场景:在controller中调用service的方法,在service的方法中远程调用。

好处:原来的写法要将url中的参数重新在controller中封装成一个map或者对象传递给restTemplate对象, restTemplate对象再解析这个map或者对象 =》消除这个封装的过程。

1.     单一返回值

1.     添加依赖

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-feign</artifactId>

        </dependency>

2.     添加远程调用接口

package com.svw.tbox.tcloud.user.consumer.api;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import com.svw.tbox.tcloud.user.consumer.entity.User;

@FeignClient(name = "tcloud-user-provider")

publicinterface UserFeignClient {

  @RequestMapping(value = "/likeName/{name}", method = RequestMethod.GET)

  public List<User> findByName(@PathVariable("name") String name);

}

3.     改造controller

package com.svw.tbox.tcloud.user.consumer.controller;

import java.util.List;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RestController;

import com.svw.tbox.tcloud.user.consumer.entity.User;

import com.svw.tbox.tcloud.user.consumer.feign.UserFeignClient;

@RestController

publicclass TboxController {

    privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(TboxController.class);

    @Autowired

    private LoadBalancerClient loadBalancerClient;

    @GetMapping("/log-instance")

    public String logUserInstance(){

        ServiceInstance serviceInstance=this.loadBalancerClient.choose("tcloud-user-provider");

        //打印当前选择的是哪个节点

        TboxController.LOGGER.info("{}:{}:{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());

        return"hello";

    }

    @Autowired

    private UserFeignClient userFeignClient;

    @GetMapping("/user/{name}")

    public List<User> likeName(@PathVariable String name){

        returnuserFeignClient.findByName(name);

//      return this.restTemplate.getForObject("http://localhost:8000/likeName/"+name, List.class) ;

    }

}

4.     启动类开启Feign

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

publicclass ConsumerApplication {

5.     效果:

启动eureka server两个实例

启动tcloud-user-provider两个实例

启动tcloud-user-consumer

多次访问http://localhost:9000/user/hrf

两个provider控制台打印查询数据库命令(开启sql显示命令)

2.     多个多种类型的返回值

1.     调用方

Map<String,Object> reMap =gatewayAuthService.isThrereARightToAccessAndGetUserInfo(accessToken, requestUri, method);

boolean isAccessTokenExistInRedis = (boolean) reMap.get("isAccessTokenExistInRedis");

Map<String, Object> userInfo = (LinkedHashMap<String, Object>)reMap.get("userInfo");

    public Map<String,Object> isThrereARightToAccessAndGetUserInfo(String accessToken, String requestUri, String method) {

       Map<String,String> map = new HashMap<>();

       map.put("accessToken", accessToken);

       map.put("requestUri", requestUri);

       map.put("method", method);

       returnauthFeignClient.isThrereARightToAccessAndGetUserInfo(map);

    }

@FeignClient(name = "tcloud-security-auth")

publicinterface AuthFeignClient {

    @RequestMapping(value = "/tokenAuth/isThrereARightToAccessAndGetUserInfo", method = RequestMethod.GET)

    public Map<String,Object> isThrereARightToAccessAndGetUserInfo(@RequestParam Map<String,String> map);

}

publicclass AuthFeignClientFallback implements AuthFeignClient {

    @Override

    public Map<String,Object> isThrereARightToAccessAndGetUserInfo(Map<String, String> map) {

       Map<String,Object> remap = new HashMap<>();

       remap.put("isAccessTokenExistInRedis", false);

       remap.put("isUserInfoExists", false);

       remap.put("isThrereARightToAccess", false);

       remap.put("userInfo", new LinkedHashMap<>());

       returnremap;

    }

}

2.     生产方

@RestController

@RequestMapping("/tokenAuth")

publicclass TokenController {

    @Autowired

    private TokenService tokenService;

    @RequestMapping(value = "/isThrereARightToAccessAndGetUserInfo", method = RequestMethod.GET)

    public Map<String,Object> isThrereARightToAccessAndGetUserInfo(@RequestParam Map<String,String> map) {

       String accessToken = map.get("accessToken");

       String requestUri = map.get("requestUri");

       String method = map.get("method");

       returntokenService.isThrereARightToAccessAndGetUserInfo(accessToken,requestUri,method);

    }

}

    public Map<String,Object> isThrereARightToAccessAndGetUserInfo(String accessToken, String requestUri, String method) {

       Map<String,Object> reMap = new HashMap<>();

       if(!checkAccessTokenExistInRedis(accessToken)) {

           reMap.put("isAccessTokenExistInRedis", false);

       }else {……

           if(uv==null) {

……

           }else {

              reMap.put("userInfo", uv);

              reMap.put("isUserInfoExists", true);

           }

……

    reMap.put("isThrereARightToAccess" ,true);

       }

       returnreMap;

    }

继续阅读