-
注意: feign 默认开启支持ribbon负载均衡
-
在Eureka测试 Order 服务中 pom中添加依赖,注意feign是从Eureka注册中心中获取请求地址,所以也需要Eureka客户端依赖;
Order项目地址:https://github.com/liangxifeng833/springcloud/tree/master/eureka/order<!-- SpringCloud整合Eureka客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- SpringCloud整合feign客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
项目启动文件
OrderApplicaton.java
新增注解@EnableFeignClients
:package lxf.order; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication //@EnableEurekaClient 将当前服务注册到Eureka @EnableEurekaClient //开启feign客户端权限 @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } } ```
-
在
order
会员服务中,写fegin
接口请求member
服务MemberApiFeign.java
package lxf.order.api.feign; import lxf.order.api.DomainResponse; 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 java.util.Map; /** * 请求远程member服务feign接口 */ //app-member就是会员服务注册到Eureka的服务别名 @FeignClient(name="app-member") public interface MemberApiFeign { //需要请求member服务的getMember方法 @GetMapping("/getMember") public String getFeignMember(); //需要请求member服务的addMember方法 @PostMapping("/addMember") public DomainResponse addFeignMember(@RequestBody Map<String,Object> map); }
-
MemberFeignController.java
调用接口请求member服务package lxf.order.api.feign; import lxf.order.api.DomainResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * 使用feign客户端远程请求member服务的get和post请求测试 */ @RestController public class MemberFeignController { @Autowired private MemberApiFeign memberApiFeign; @RequestMapping("/feignMember") public DomainResponse feignMember() { //测试get请求 //return memberApiFeign.getFeignMember(); //测试post请求 Map<String,Object> map = new HashMap<String,Object>(); map.put("lan","php"); map.put("db","mysql"); DomainResponse res = memberApiFeign.addFeignMember(map); System.out.println("response = " + res); return res; } }
-
member服务的api实现代码如下:
git地址: https://github.com/liangxifeng833/springcloud/blob/master/eureka/member/src/main/java/lxf/member/api/MemberApiController.javapackage lxf.member.api; import org.springframework.beans.factory.annotation.Value; 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.RestController; import java.util.Map; @RestController public class MemberApiController { @Value("${server.port}") private String serverPort; @GetMapping("/getMember") public String getMember() { return "I am member! server port = "+serverPort; } @PostMapping("/addMember") public DomainResponse addMember(@RequestBody Map<String,Object> map) { return DomainResponse.ofSuccess(map); } }
########################################################
重构feign客户端
- 因为
order
服务中需要定义feign
接口,该接口其实就是要访问member
中的getMember
接口,我们可以建立接口项目,然后在order
和member
中直接实现和调用接口项目中的即可,这样就不想用写重复的代码.多个项目互相依赖请查看:IDEA创建多个模块MavenSpringBoot项目; -
先新建parent maven项目,然后在parent项目右键->Module->选择maven项目创建各个子项目.项目创建好的目录结构是:
image.png
以上目录结构说明:
api-service
中包含api-member-service
和api-order-service
这两个service只是接口和实体
没有实现;
api-member-service-impl
是具体的会员服务实现,该项目依赖api-member-service
接口.
api-order-service-impl
是具体的订单服务实现,该项目依赖api-order-servcie
和api-member-service
两个接口项目,在该项目中使用feign
客户端调用远程会员服务接口如下:
import api.member.service.IMemberServcie;
import org.springframework.cloud.openfeign.FeignClient;
/**
* 使用feign客户端调用远程会员服务接口
* 该接口继承会员服务api-member-service中的IMemberService接口
* 就不需要重复写接口了
*/
@FeignClient("app-member")
public interface MemberServiceFeign extends IMemberServcie {
}
OrderServiceImpl
实现接口并具体实现远程调用内容如下:
package order.service.impl;
import api.member.entity.User;
import order.service.IOrderService;
import order.service.feign.MemberServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 订单服务controller 实现order-service项目中的接口
*/
@RestController
public class OrderServiceImpl implements IOrderService {
@Autowired
private MemberServiceFeign memberServiceFeign;
@RequestMapping("/orderToMember")
@Override
public String orderToMember(String name) {
User user = memberServiceFeign.getMember(name);
return user==null ? "找不到用户信息" : user.toString();
}
}
成功访问结果如下:(注意启动项目顺序:eureka-> api-member-service-impl-> api-order-service-impl
)公共接口api-server不需要配置启动文件因为只有接口所以无需启动.
- 然后在parent工程的pom中引入如下,就属于spring-boot工程了.就可以在项目中新建包了,否则显示的是新建目录.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
-
特别注意: 如果该项目是war包,则在项目启动文件中必须
extends SpringBootServletInitializer
, 且有SpringApplicationBuilder
方法,否则war包部署到tomcat后会出现访问404页面.
package order.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
//@EnableEurekaClient 将当前服务注册到Eureka
@EnableEurekaClient
//使用feign客户端调用远程http服务
@EnableFeignClients
public class OrderApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(OrderApplication.class);
}
}
-
然后在
image.pngapi-member-service
的src/main/jave
中右键->创建package:api.member.service
,然后在这个包内创建IMemberServcie
接口
-
注意:即使按着该文章创建好后,在IDEA中启动服务后通过浏览器可以正常方法(IDEA自动帮忙管理依赖),但是通过
image.pngmavn clean package
打包后发现依赖包找不到:IDEA maven 多模块打包问题总结,这是因为依赖包需要放到私服中,所以就需要搭建内部maven私服:自己手动搭建Nexus私服,
具体项目代码地址:https://github.com/liangxifeng833/springcloud/tree/master/parent
网友评论