目标:
改进上一章讲的客户端调用方式,集成feign,简化客户端调用
简介:
Fegin是一个声明式的web服务客户端,它使得编写web服务客户端变得更加容易,其形态类似于mybatis对于dao层的封装。
开工:
- 在commons创建返回vo模型,以便多系统共用,具体业务意义不在这里讨论
--------------------------------------请求vo----------------------------------
package open.template.work.commons.vo.udm.request;
import open.template.work.commons.vo.udm.BaseRequestVo;
public class TaskRequestVo extends BaseRequestVo {
/**
* 本服务应用名
*/
private String appName;
/**
* 任务桶id
*/
private String bucketId;
。。。。
}
--------------------------------------返回vo----------------------------------
package open.template.work.commons.vo.udm.resposne;
import open.template.work.commons.vo.udm.BaseResponseVo;
/**
* 任务信息
*/
public class TaskReponseVo extends BaseResponseVo {
/**
* 任务桶id
*/
private String bucketId;
/**
* 任务id
*/
private String taskId;
/**
* 状态
*/
private String status;
。。。。。。
}
- 服务端添加新的restapi,先模拟返回此vo,因为入参是对象,所以需要添加@RequestBody 注解
@RestController
public class TaskInfoApi {
@PostMapping("/task/get")
public TaskReponseVo popTaskInfo(@RequestBody TaskRequestVo vo){
System.out.println("尝试获取桶"+vo.getBucketId()+"任务数据");
TaskReponseVo taskInfoDto = new TaskReponseVo();
taskInfoDto.setStatus("1");
taskInfoDto.setTaskId(UUID.randomUUID().toString());
return taskInfoDto;
}
}
- 客户端添加feign配置,
首先添加feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
然后添加启动feign注解,并指定扫描的feign包
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "open.template.work.udm.client.feign")
public class UdmClientApplication {
public static void main(String[] args) {
SpringApplication.run(UdmClientApplication.class, args);
}
@Bean
public IRule ribbonRoundRobinRule() {
return new RandomRule();
}
}
添加feign声明式接口
package open.template.work.udm.client.feign;
import open.template.work.commons.constants.CloudServerDirectory;
import open.template.work.commons.vo.udm.request.TaskRequestVo;
import open.template.work.commons.vo.udm.resposne.TaskReponseVo;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = CloudServerDirectory.UDM_SERVER)
public interface UdmServerTaskFegin {
@PostMapping("/task/get")
TaskReponseVo getTaskInfo(@RequestBody TaskRequestVo vo);
}
最后在service层和api层添加对应调用测试逻辑,可以看到此时LoadBalancerClient方式和feign方式是共存的,feign会自动集成eureka和ribbon,所以此时的负载策略就是上章通过IRule和配置文件指定的负载规则,对于eureia我们通过@FeignClient(name = CloudServerDirectory.UDM_SERVER)注解在feign已指定,不需在拼接url,完美集成。
package open.template.work.udm.client.service.impl;
import open.template.work.commons.constants.CloudServerDirectory;
import open.template.work.commons.http.RestTemplateFactory;
import open.template.work.commons.vo.udm.request.TaskRequestVo;
import open.template.work.commons.vo.udm.resposne.TaskReponseVo;
import open.template.work.udm.client.feign.UdmServerClient;
import open.template.work.udm.client.feign.UdmServerTaskFegin;
import open.template.work.udm.client.service.UdmServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
@Service
public class UdmServerServiceImpl implements UdmServerService {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private UdmServerClient udmServerClient;
@Autowired
private UdmServerTaskFegin udmServerTaskClient;
@Override
public String checkServerInfo() {
ServiceInstance instance = loadBalancerClient.choose(CloudServerDirectory.UDM_SERVER);
return RestTemplateFactory.getTemplate().getForObject(CloudServerDirectory.getServerUrl(instance.getHost(),instance.getPort())+"hello",String.class);
}
@Override
public String checkServer2(){
return udmServerClient.hello();
}
@Override
public TaskReponseVo getTaskInfo(String bucketId) {
TaskRequestVo vo=new TaskRequestVo();
vo.setBucketId(bucketId);
return udmServerTaskClient.getTaskInfo(vo);
}
}
- 都配了,启动服务测试一下
服务端日志:
完工!