前言
在结束技术选择和模块化项目搭建之后。我们的spring boot项目就可以启动了。这时候就需要聊到微服务的一个重大作用,RPC调用
文章参考:
feign问题处理:http://www.imooc.com/article/289005
如何调用feign:https://segmentfault.com/a/1190000012496398
feign
feign接口调用是spring cloud下常用的RPC调用,自带Spring Cloud Ribbon 与 Spring Cloud Hystrix,提供了方便的负载均衡和断融,降级等服务
代码
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
Service文件
import com.chen.service.requestDTO.TestHelloRequestDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "SERVICE-A")
@RequestMapping("/test")
//@FeignClient注解value必须与服务客户端application.yml配置中服务命名对应
public interface TestService {
@RequestMapping("/hello")
public String hello(TestHelloRequestDTO requestDTO);
@RequestMapping("/hi")
public String hi();
}
serviceimpl文件
import com.alibaba.fastjson.JSON;
import com.chen.service.requestDTO.TestHelloRequestDTO;
import com.chen.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController
public class TestServiceImpl implements TestService {
@Override
public String hello(@RequestBody TestHelloRequestDTO requestDTO) {
log.info(JSON.toJSONString(requestDTO));
return "hello";
}
@Override
public String hi() {
return "hi";
}
}
启动类注解
@SpringBootApplication
//Spring boot启动类
@EnableEurekaClient
//eureka 注册类
@RestController
//一个spring mvc控制
@EnableDiscoveryClient
//eureka 发现,如果单机应用,需要注释
//@EnableFeignClients(basePackages = {"com.chen.service"})
//feign包扫描
使用
坑点:
1.spring cloud feign接口无法调用。接口404或者调用后500,因为我把启动类的位置调整了。我们的默认包为com.chen.xxx,则启动类要放在com.chen下面
2.项目启动失败,原因有二,一是@FeignClient(name = “SERVICE-A”)注意括号中的name要和ymp配置中的服务命名对应,
3.@RequestMapping这个注解我喜欢在类上注解一个,方法上也注解一个,这样可以方便的控制url的头部内容,但是feign有一个bug,无法做到,虽然这个bug之后修复了,但是老版本的feign不能再类上注解@RequestMapping,问题解决可以参考我上面发的链接
2020.8.19重新更新
重写:这部分的的时候我当初没有搞明白服务提供的原理,上面代码的@EnableFeignClients这个注释会扫描包。但是如果你这个应用只提供服务但是不调用其他服务。不需要开启这个注释,如果有其他应用的服务需要调用,才需要开启。而且这个扫描包的范围,只能扫描其他服务的包,千万不能扫描应用本身的包。不然就会提示方法重复。
核心说法就是使用@EnableFeignClients的扫描的时候如果把自己方法的feign接口也扫描的话会和feign的实现类互相冲突,导致spring认为有2个相同的url地址而启动失败。也有一些解决办法推荐重写spring的相关方法,就是我开始的链接上放的,但是其实是没有必要的,因为你调用微服务本来就不会调用到自身,所以本来@EnableFeignClients这个注解的扫描包就是要控制的颗粒度很细才行。不能直接一个大范围直接扫描。这样才会导致我之前遇到的3的问题
具体使用方法:
1.直接用serviceimpl+@Controller注解,即可调用对应的web接口返回结果
2.其他微服务,调用@Resource注解注入Service然后调用方法即可
结束
这样我们的基本的接口调用和MCV分层架构中的controller层就算是ok了。
github地址:https://github.com/alex9567/SpringCloudScaffold